Eclipse SUMO - Simulation of Urban MObility
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>
23 #include <netedit/GNEViewParent.h>
29 
30 #include "GNEContainer.h"
31 #include "GNEPerson.h"
32 #include "GNEPersonTrip.h"
33 #include "GNERide.h"
34 #include "GNERoute.h"
35 #include "GNERouteDistribution.h"
36 #include "GNERouteHandler.h"
37 #include "GNEStop.h"
38 #include "GNETranship.h"
39 #include "GNETransport.h"
40 #include "GNEVehicle.h"
41 #include "GNEVType.h"
42 #include "GNEVTypeDistribution.h"
43 #include "GNEWalk.h"
44 #include "GNEStopPlan.h"
45 
46 // ===========================================================================
47 // member method definitions
48 // ===========================================================================
49 
50 GNERouteHandler::GNERouteHandler(const std::string& file, GNENet* net, const bool allowUndoRedo, const bool overwrite) :
51  RouteHandler(file, false),
52  myNet(net),
53  myPlanObject(new CommonXMLStructure::SumoBaseObject(nullptr)),
54  myAllowUndoRedo(allowUndoRedo),
55  myOverwrite(overwrite) {
56 }
57 
58 
60  delete myPlanObject;
61 }
62 
63 
64 void
66  // check if loaded type is a default type
67  if (DEFAULT_VTYPES.count(vTypeParameter.id) > 0) {
68  // overwrite default vehicle type
70  } else if (!checkDuplicatedDemandElement(SUMO_TAG_VTYPE, vTypeParameter.id)) {
71  writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE), vTypeParameter.id));
72  } else {
73  // create vType/pType using myCurrentVType
74  GNEDemandElement* vType = new GNEVType(myNet, vTypeParameter);
75  // check if add this vType to a distribution
76  GNEDemandElement* vTypeDistribution = nullptr;
77  if (sumoBaseObject->getParentSumoBaseObject() && sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VTYPE_DISTRIBUTION) {
79  }
80  if (myAllowUndoRedo) {
81  myNet->getViewNet()->getUndoList()->begin(vType, TL("add ") + vType->getTagStr() + " '" + vTypeParameter.id + "'");
83  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vType, true), true);
84  if (vTypeDistribution) {
85  vTypeDistribution->addDistributionKey(vType, vType->getAttributeDouble(SUMO_ATTR_PROB), myNet->getViewNet()->getUndoList());
86  }
88  } else {
90  if (vTypeDistribution) {
91  vTypeDistribution->addDistributionKey(vType, vType->getAttributeDouble(SUMO_ATTR_PROB));
92  }
93  vType->incRef("buildVType");
94  }
95  }
96 }
97 
98 
99 void
100 GNERouteHandler::buildVTypeDistribution(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const int deterministic,
101  const std::vector<std::string>& vTypeIDs, const std::vector<double>& probabilities) {
102  // declare vector with vType and their probabilities
103  std::vector<const GNEDemandElement*> vTypes;
104  // first check conditions
106  writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE)));
107  } else if (getDistributionElements(sumoBaseObject, SUMO_TAG_VTYPE, vTypeIDs, probabilities, vTypes)) {
108  // create distributions
109  GNEVTypeDistribution* vTypeDistribution = new GNEVTypeDistribution(myNet, id, deterministic);
110  if (myAllowUndoRedo) {
111  myNet->getViewNet()->getUndoList()->begin(vTypeDistribution, TL("add ") + vTypeDistribution->getTagStr() + " '" + id + "'");
113  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vTypeDistribution, true), true);
114  // add all distributions
115  for (int i = 0; i < (int)vTypes.size(); i++) {
116  vTypeDistribution->addDistributionKey(vTypes.at(i), probabilities.at(i), myNet->getViewNet()->getUndoList());
117  }
118  myNet->getViewNet()->getUndoList()->end();
119  } else {
120  myNet->getAttributeCarriers()->insertDemandElement(vTypeDistribution);
121  // add all distributions directly
122  for (int i = 0; i < (int)vTypes.size(); i++) {
123  vTypeDistribution->addDistributionKey(vTypes.at(i), probabilities.at(i));
124  }
125  vTypeDistribution->incRef("buildVTypeDistribution");
126  }
127  }
128 }
129 
130 
131 void
132 GNERouteHandler::buildRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, SUMOVehicleClass vClass,
133  const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
134  const double probability, const Parameterised::Map& routeParameters) {
135  // parse edges
136  const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
137  // check conditions
139  writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_ROUTE), id));
140  } else if (edges.size() > 0) {
141  // create GNERoute
142  GNEDemandElement* route = new GNERoute(myNet, id, vClass, edges, color, repeat, cycleTime, routeParameters);
143  // check if add this route to a distribution
144  GNEDemandElement* routeDistribution = nullptr;
145  if (sumoBaseObject && sumoBaseObject->getParentSumoBaseObject() && sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_ROUTE_DISTRIBUTION) {
147  }
148  if (myAllowUndoRedo) {
149  myNet->getViewNet()->getUndoList()->begin(route, TL("add ") + route->getTagStr() + " '" + id + "'");
151  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
152  if (routeDistribution) {
153  routeDistribution->addDistributionKey(route, probability, myNet->getViewNet()->getUndoList());
154  }
155  myNet->getViewNet()->getUndoList()->end();
156  } else {
158  for (const auto& edge : edges) {
159  edge->addChildElement(route);
160  }
161  if (routeDistribution) {
162  routeDistribution->addDistributionKey(route, probability);
163  }
164  route->incRef("buildRoute");
165  }
166  }
167 }
168 
169 
170 void
171 GNERouteHandler::buildEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::vector<std::string>& edgeIDs,
172  const RGBColor& color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map& routeParameters) {
173  // first create vehicle/flow
174  const SUMOVehicleParameter& vehicleParameters = sumoBaseObject->getParentSumoBaseObject()->getVehicleParameter();
175  const SumoXMLTag vehicleTag = (sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VEHICLE) ? GNE_TAG_VEHICLE_WITHROUTE :
177  sumoBaseObject->getParentSumoBaseObject()->getTag();
178  // parse route edges
179  const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
180  // check if ID is duplicated
181  if ((edges.size() > 0) && !isVehicleIdDuplicated(vehicleParameters.id)) {
182  // obtain type
183  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
184  if (type == nullptr) {
185  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
186  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)edges.front()->getLanes().size() < vehicleParameters.departLane)) {
187  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
188  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
189  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)));
190  } else {
191  // create vehicle using vehicleParameters
192  GNEDemandElement* vehicle = new GNEVehicle(vehicleTag, myNet, type, vehicleParameters);
193  // create embedded route
194  GNEDemandElement* route = new GNERoute(myNet, vehicle, edges, color, repeat, cycleTime, routeParameters);
195  if (myAllowUndoRedo) {
196  myNet->getViewNet()->getUndoList()->begin(route, TL("add ") + route->getTagStr() + " in '" + vehicle->getID() + "'");
198  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
199  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
200  myNet->getViewNet()->getUndoList()->end();
201  } else {
204  type->addChildElement(vehicle);
205  vehicle->addChildElement(route);
206  for (const auto& edge : edges) {
207  edge->addChildElement(route);
208  }
209  vehicle->incRef("buildEmbeddedRoute");
210  route->incRef("buildEmbeddedRoute");
211  }
212  }
213  }
214 }
215 
216 
217 void
219  const std::vector<std::string>& routeIDs, const std::vector<double>& probabilities) {
220  // declare vector with route and their probabilities
221  std::vector<const GNEDemandElement*> routes;
222  // first check conditions
224  writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_ROUTE)));
225  } else if (getDistributionElements(sumoBaseObject, SUMO_TAG_ROUTE, routeIDs, probabilities, routes)) {
226  // create distributions
227  GNERouteDistribution* routeDistribution = new GNERouteDistribution(myNet, id);
228  if (myAllowUndoRedo) {
229  myNet->getViewNet()->getUndoList()->begin(routeDistribution, TL("add ") + routeDistribution->getTagStr() + " '" + id + "'");
231  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(routeDistribution, true), true);
232  // add all distributions
233  for (int i = 0; i < (int)routes.size(); i++) {
234  routeDistribution->addDistributionKey(routes.at(i), probabilities.at(i), myNet->getViewNet()->getUndoList());
235  }
236  myNet->getViewNet()->getUndoList()->end();
237  } else {
238  myNet->getAttributeCarriers()->insertDemandElement(routeDistribution);
239  // add all distributions directly
240  for (int i = 0; i < (int)routes.size(); i++) {
241  routeDistribution->addDistributionKey(routes.at(i), probabilities.at(i));
242  }
243  routeDistribution->incRef("buildRouteDistribution");
244  }
245  }
246 }
247 
248 
249 void
251  // first check if ID is duplicated
252  if (!isVehicleIdDuplicated(vehicleParameters.id)) {
253  // obtain routes and vtypes
254  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
256  if (type == nullptr) {
257  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
258  } else if (route == nullptr) {
259  writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
260  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
261  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
262  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
263  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)));
264  } else {
265  // create vehicle using vehicleParameters
266  GNEDemandElement* vehicle = new GNEVehicle(SUMO_TAG_VEHICLE, myNet, type, route, vehicleParameters);
267  if (myAllowUndoRedo) {
268  myNet->getViewNet()->getUndoList()->begin(vehicle, TL("add ") + vehicle->getTagStr() + " '" + vehicleParameters.id + "'");
270  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
271  myNet->getViewNet()->getUndoList()->end();
272  } else {
274  // set vehicle as child of type and Route
275  type->addChildElement(vehicle);
276  route->addChildElement(vehicle);
277  vehicle->incRef("buildVehicleOverRoute");
278  }
279  }
280  }
281 }
282 
283 
284 void
286  // first check if ID is duplicated
287  if (!isVehicleIdDuplicated(vehicleParameters.id)) {
288  // obtain routes and vtypes
289  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
291  if (type == nullptr) {
292  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
293  } else if (route == nullptr) {
294  writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
295  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
296  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
297  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
298  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)));
299  } else {
300  // create flow or trips using vehicleParameters
301  GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_ROUTE, myNet, type, route, vehicleParameters);
302  if (myAllowUndoRedo) {
303  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
305  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
306  myNet->getViewNet()->getUndoList()->end();
307  } else {
309  // set flow as child of type and Route
310  type->addChildElement(flow);
311  route->addChildElement(flow);
312  flow->incRef("buildFlowOverRoute");
313  }
314  }
315  }
316 }
317 
318 
319 void
321  const std::string& fromEdgeID, const std::string& toEdgeID) {
322  // parse edges
323  const auto fromEdge = parseEdge(SUMO_TAG_TRIP, fromEdgeID);
324  const auto toEdge = parseEdge(SUMO_TAG_TRIP, toEdgeID);
325  // set via attribute
326  if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
327  vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
328  }
329  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
330  if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
331  // obtain type
332  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
333  if (type == nullptr) {
334  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
335  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
336  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
337  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
338  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)));
339  } else {
340  // create trip or flow using tripParameters
341  GNEDemandElement* trip = new GNEVehicle(SUMO_TAG_TRIP, myNet, type, fromEdge, toEdge, vehicleParameters);
342  if (myAllowUndoRedo) {
343  myNet->getViewNet()->getUndoList()->begin(trip, TL("add ") + trip->getTagStr() + " '" + vehicleParameters.id + "'");
345  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(trip, true), true);
346  myNet->getViewNet()->getUndoList()->end();
347  } else {
349  // set vehicle as child of type
350  type->addChildElement(trip);
351  trip->incRef("buildTrip");
352  // add reference in all edges
353  fromEdge->addChildElement(trip);
354  toEdge->addChildElement(trip);
355  }
356  }
357  }
358 }
359 
360 
361 void
363  const std::string& fromJunctionID, const std::string& toJunctionID) {
364  // parse junctions
365  const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
366  const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
367  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
368  if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
369  // obtain type
370  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
371  if (type == nullptr) {
372  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
373  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
374  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
375  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
376  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)));
377  } else {
378  // create trip using vehicleParameters
379  GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
380  if (myAllowUndoRedo) {
381  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
383  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
384  myNet->getViewNet()->getUndoList()->end();
385  } else {
387  // set vehicle as child of type
388  type->addChildElement(flow);
389  flow->incRef("buildFlow");
390  // add reference in all junctions
391  fromJunction->addChildElement(flow);
392  toJunction->addChildElement(flow);
393  }
394  }
395  }
396 }
397 
398 
399 void
401  const std::string& fromTAZID, const std::string& toTAZID) {
402  // parse TAZs
403  const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
404  const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
405  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
406  if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
407  // obtain type
408  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
409  if (type == nullptr) {
410  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
411  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
412  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
413  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
414  writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
415  } else {
416  // create trip using vehicleParameters
417  GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
418  if (myAllowUndoRedo) {
419  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
421  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
422  myNet->getViewNet()->getUndoList()->end();
423  } else {
425  // set vehicle as child of type
426  type->addChildElement(flow);
427  flow->incRef("buildFlow");
428  // add reference in all TAZs
429  fromTAZ->addChildElement(flow);
430  toTAZ->addChildElement(flow);
431  }
432  }
433  }
434 }
435 
436 
437 void
439  const std::string& fromEdgeID, const std::string& toEdgeID) {
440  // parse edges
441  const auto fromEdge = parseEdge(SUMO_TAG_FLOW, fromEdgeID);
442  const auto toEdge = parseEdge(SUMO_TAG_FLOW, toEdgeID);
443  // set via attribute
444  if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
445  vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
446  }
447  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
448  if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
449  // obtain type
450  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
451  if (type == nullptr) {
452  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
453  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
454  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
455  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
456  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)));
457  } else {
458  // create trip or flow using tripParameters
459  GNEDemandElement* flow = new GNEVehicle(SUMO_TAG_FLOW, myNet, type, fromEdge, toEdge, vehicleParameters);
460  if (myAllowUndoRedo) {
461  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
463  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
464  myNet->getViewNet()->getUndoList()->end();
465  } else {
467  // set vehicle as child of type
468  type->addChildElement(flow);
469  flow->incRef("buildFlow");
470  // add reference in all edges
471  fromEdge->addChildElement(flow);
472  toEdge->addChildElement(flow);
473  }
474  }
475  }
476 }
477 
478 
479 void
481  const std::string& fromJunctionID, const std::string& toJunctionID) {
482  // parse junctions
483  const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
484  const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
485  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
486  if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
487  // obtain type
488  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
489  if (type == nullptr) {
490  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
491  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
492  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
493  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
494  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)));
495  } else {
496  // create flow using vehicleParameters
497  GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
498  if (myAllowUndoRedo) {
499  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
501  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
502  myNet->getViewNet()->getUndoList()->end();
503  } else {
505  // set vehicle as child of type
506  type->addChildElement(flow);
507  flow->incRef("buildFlow");
508  // add reference in all junctions
509  fromJunction->addChildElement(flow);
510  toJunction->addChildElement(flow);
511  }
512  }
513  }
514 }
515 
516 
517 void
519  const std::string& fromTAZID, const std::string& toTAZID) {
520  // parse TAZs
521  const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
522  const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
523  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
524  if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
525  // obtain type
526  GNEDemandElement* type = getType(vehicleParameters.vtypeid);
527  if (type == nullptr) {
528  writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
529  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
530  writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
531  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
532  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)));
533  } else {
534  // create flow using vehicleParameters
535  GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
536  if (myAllowUndoRedo) {
537  myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
539  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
540  myNet->getViewNet()->getUndoList()->end();
541  } else {
543  // set vehicle as child of type
544  type->addChildElement(flow);
545  flow->incRef("buildFlow");
546  // add reference in all TAZs
547  fromTAZ->addChildElement(flow);
548  toTAZ->addChildElement(flow);
549  }
550  }
551  }
552 }
553 
554 
555 void
556 GNERouteHandler::buildPerson(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personParameters) {
557  // first check if ID is duplicated
558  if (!isPersonIdDuplicated(personParameters.id)) {
559  // obtain type
560  GNEDemandElement* type = getType(personParameters.vtypeid);
561  if (type == nullptr) {
562  writeError(TLF("Invalid vehicle type '%' used in % '%'.", personParameters.vtypeid, toString(personParameters.tag), personParameters.id));
563  } else {
564  // create person using personParameters
565  GNEDemandElement* person = new GNEPerson(SUMO_TAG_PERSON, myNet, type, personParameters);
566  if (myAllowUndoRedo) {
567  myNet->getViewNet()->getUndoList()->begin(person, TL("add ") + person->getTagStr() + " '" + personParameters.id + "'");
569  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
570  myNet->getViewNet()->getUndoList()->end();
571  } else {
573  // set person as child of type
574  type->addChildElement(person);
575  person->incRef("buildPerson");
576  }
577  }
578  }
579 }
580 
581 
582 void
583 GNERouteHandler::buildPersonFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personFlowParameters) {
584  // first check if ID is duplicated
585  if (!isPersonIdDuplicated(personFlowParameters.id)) {
586  // obtain type
587  GNEDemandElement* type = getType(personFlowParameters.vtypeid);
588  if (type == nullptr) {
589  writeError(TLF("Invalid vehicle type '%' used in % '%'.", personFlowParameters.vtypeid, toString(personFlowParameters.tag), personFlowParameters.id));
590  } else {
591  // create personFlow using personFlowParameters
592  GNEDemandElement* personFlow = new GNEPerson(SUMO_TAG_PERSONFLOW, myNet, type, personFlowParameters);
593  if (myAllowUndoRedo) {
594  myNet->getViewNet()->getUndoList()->begin(personFlow, TL("add ") + personFlow->getTagStr() + " '" + personFlowParameters.id + "'");
596  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personFlow, true), true);
597  myNet->getViewNet()->getUndoList()->end();
598  } else {
600  // set personFlow as child of type
601  type->addChildElement(personFlow);
602  personFlow->incRef("buildPersonFlow");
603  }
604  }
605  }
606 }
607 
608 
609 void
611  const std::string& fromEdgeID, const std::string& fromTAZID, const std::string& fromJunctionID, const std::string& fromBusStopID, const std::string& fromTrainStopID,
612  const std::string& toEdgeID, const std::string& toTAZID, const std::string& toJunctionID, const std::string& toBusStopID, const std::string& toTrainStopID,
613  double arrivalPos, const std::vector<std::string>& types, const std::vector<std::string>& modes, const std::vector<std::string>& lines) {
614  // parse parents
615  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
616  GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
617  GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
618  GNEAdditional* fromTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, fromTAZID, false);
620  GNEJunction* fromJunction = myNet->getAttributeCarriers()->retrieveJunction(fromJunctionID, false);
621  GNEJunction* toJunction = myNet->getAttributeCarriers()->retrieveJunction(toJunctionID, false);
622  GNEAdditional* fromBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, fromBusStopID, false);
623  GNEAdditional* toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toBusStopID, false);
624  GNEAdditional* fromTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, fromTrainStopID, false);
625  GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
626  // chek if we're parsing the train stop as a busStop
627  if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
628  toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
629  toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
630  }
631  // check if overwritte previous elements
632  if (getPreviousPlanEdge(sumoBaseObject)) {
633  fromEdge = getPreviousPlanEdge(sumoBaseObject);
634  }
635  if (getPreviousPlanTAZ(sumoBaseObject)) {
636  fromTAZ = getPreviousPlanTAZ(sumoBaseObject);
637  }
638  if (getPreviousPlanJunction(sumoBaseObject)) {
639  fromJunction = getPreviousPlanJunction(sumoBaseObject);
640  }
641  if (getPreviousPlanBusStop(sumoBaseObject)) {
642  fromBusStop = getPreviousPlanBusStop(sumoBaseObject);
643  }
644  if (getPreviousPlanTrainStop(sumoBaseObject)) {
645  toTrainStop = getPreviousPlanTrainStop(sumoBaseObject);
646  }
647  // check conditions
648  if (personParent == nullptr) {
649  WRITE_WARNING(TL("invalid person parent"));
650  } else if (GNEPersonTrip::getPersonTripTagIcon(fromEdge, toEdge, fromTAZ, toTAZ, fromJunction, toJunction,
651  fromBusStop, toBusStop, fromTrainStop, toTrainStop).first == SUMO_TAG_NOTHING) {
652  WRITE_WARNING(TL("invalid combination for personTrip"));
653  } else {
654  // build person trip
655  GNEDemandElement* personTrip = GNEPersonTrip::buildPersonTrip(myNet, personParent,
656  fromEdge, fromTAZ, fromJunction, fromBusStop, fromTrainStop,
657  toEdge, toTAZ, toJunction, toBusStop, toTrainStop,
658  arrivalPos, types, modes, lines);
659  // continue depending of undo.redo
660  if (myAllowUndoRedo) {
661  myNet->getViewNet()->getUndoList()->begin(personTrip, TLF("add % in '%'", personTrip->getTagStr(), personParent->getID()));
663  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
664  myNet->getViewNet()->getUndoList()->end();
665  } else {
667  // set child references
668  personParent->addChildElement(personTrip);
669  if (fromEdge) {
670  fromEdge->addChildElement(personTrip);
671  }
672  if (fromTAZ) {
673  fromTAZ->addChildElement(personTrip);
674  }
675  if (fromJunction) {
676  fromJunction->addChildElement(personTrip);
677  }
678  if (fromBusStop) {
679  fromBusStop->addChildElement(personTrip);
680  }
681  if (fromTrainStop) {
682  fromTrainStop->addChildElement(personTrip);
683  }
684  if (toEdge) {
685  toEdge->addChildElement(personTrip);
686  }
687  if (toTAZ) {
688  toTAZ->addChildElement(personTrip);
689  }
690  if (toJunction) {
691  toJunction->addChildElement(personTrip);
692  }
693  if (toBusStop) {
694  toBusStop->addChildElement(personTrip);
695  }
696  if (toTrainStop) {
697  toTrainStop->addChildElement(personTrip);
698  }
699  personTrip->incRef("buildPersonTrip");
700  }
701  }
702 }
703 
704 
705 void
707  const std::string& fromEdgeID, const std::string& fromTAZID, const std::string& fromJunctionID, const std::string& fromBusStopID, const std::string& fromTrainStopID,
708  const std::string& toEdgeID, const std::string& toTAZID, const std::string& toJunctionID, const std::string& toBusStopID, const std::string& toTrainStopID,
709  const std::vector<std::string>& edgeIDs, const std::string& routeID, double arrivalPos) {
710  // parse parents
711  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
712  GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
713  GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
714  GNEAdditional* fromTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, fromTAZID, false);
716  GNEJunction* fromJunction = myNet->getAttributeCarriers()->retrieveJunction(fromJunctionID, false);
717  GNEJunction* toJunction = myNet->getAttributeCarriers()->retrieveJunction(toJunctionID, false);
718  GNEAdditional* fromBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, fromBusStopID, false);
719  GNEAdditional* toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toBusStopID, false);
720  GNEAdditional* fromTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, fromTrainStopID, false);
721  GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
723  std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_WALK, edgeIDs);
724  // chek if we're parsing the train stop as a busStop
725  if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
726  toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
727  toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
728  }
729  // avoid consecutive duplicated edges
730  edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
731  // check if overwritte previous elements
732  if (getPreviousPlanEdge(sumoBaseObject)) {
733  fromEdge = getPreviousPlanEdge(sumoBaseObject);
734  }
735  if (getPreviousPlanTAZ(sumoBaseObject)) {
736  fromTAZ = getPreviousPlanTAZ(sumoBaseObject);
737  }
738  if (getPreviousPlanJunction(sumoBaseObject)) {
739  fromJunction = getPreviousPlanJunction(sumoBaseObject);
740  }
741  if (getPreviousPlanBusStop(sumoBaseObject)) {
742  fromBusStop = getPreviousPlanBusStop(sumoBaseObject);
743  }
744  if (getPreviousPlanTrainStop(sumoBaseObject)) {
745  toTrainStop = getPreviousPlanTrainStop(sumoBaseObject);
746  }
747  // check conditions
748  if (personParent == nullptr) {
749  WRITE_WARNING(TL("invalid person parent"));
750  } else if (GNEWalk::getWalkTagIcon(edges, route, fromEdge, toEdge, fromTAZ, toTAZ, fromJunction, toJunction,
751  fromBusStop, toBusStop, fromTrainStop, toTrainStop).first == SUMO_TAG_NOTHING) {
752  WRITE_WARNING(TL("invalid combination for personTrip"));
753  } else {
754  // build person trip
755  GNEDemandElement* walk = GNEWalk::buildWalk(myNet, personParent,
756  fromEdge, fromTAZ, fromJunction, fromBusStop, fromTrainStop,
757  toEdge, toTAZ, toJunction, toBusStop, toTrainStop,
758  edges, route, arrivalPos);
759  // continue depending of undo.redo
760  if (myAllowUndoRedo) {
761  myNet->getViewNet()->getUndoList()->begin(walk, TLF("add % in '%'", walk->getTagStr(), personParent->getID()));
763  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
764  myNet->getViewNet()->getUndoList()->end();
765  } else {
767  // set child references
768  personParent->addChildElement(walk);
769  if (fromEdge) {
770  fromEdge->addChildElement(walk);
771  }
772  if (fromTAZ) {
773  fromTAZ->addChildElement(walk);
774  }
775  if (fromJunction) {
776  fromJunction->addChildElement(walk);
777  }
778  if (fromBusStop) {
779  fromBusStop->addChildElement(walk);
780  }
781  if (fromTrainStop) {
782  fromTrainStop->addChildElement(walk);
783  }
784  if (toEdge) {
785  toEdge->addChildElement(walk);
786  }
787  if (toTAZ) {
788  toTAZ->addChildElement(walk);
789  }
790  if (toJunction) {
791  toJunction->addChildElement(walk);
792  }
793  if (toBusStop) {
794  toBusStop->addChildElement(walk);
795  }
796  if (toTrainStop) {
797  toTrainStop->addChildElement(walk);
798  }
799  for (const auto& edge : edges) {
800  edge->addChildElement(walk);
801  }
802  if (route) {
803  route->addChildElement(walk);
804  }
805  walk->incRef("buildWalk");
806  }
807  }
808 }
809 
810 
811 void
813  const std::string& fromEdgeID, const std::string& fromBusStopID, const std::string& fromTrainStopID,
814  const std::string& toEdgeID, const std::string& toBusStopID, const std::string& toTrainStopID,
815  double arrivalPos, const std::vector<std::string>& lines) {
816  // parse parents
817  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
818  GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
819  GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
820  GNEAdditional* fromBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, fromBusStopID, false);
821  GNEAdditional* toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toBusStopID, false);
822  GNEAdditional* fromTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, fromTrainStopID, false);
823  GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
824  // chek if we're parsing the train stop as a busStop
825  if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
826  toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
827  toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
828  }
829  // check if overwritte previous elements
830  if (getPreviousPlanEdge(sumoBaseObject)) {
831  fromEdge = getPreviousPlanEdge(sumoBaseObject);
832  }
833  if (getPreviousPlanBusStop(sumoBaseObject)) {
834  fromBusStop = getPreviousPlanBusStop(sumoBaseObject);
835  }
836  if (getPreviousPlanTrainStop(sumoBaseObject)) {
837  toTrainStop = getPreviousPlanTrainStop(sumoBaseObject);
838  }
839  // check conditions
840  if (personParent == nullptr) {
841  WRITE_WARNING(TL("invalid person parent"));
842  } else if (GNERide::getRideTagIcon(fromEdge, toEdge, fromBusStop, toBusStop, fromTrainStop, toTrainStop).first == SUMO_TAG_NOTHING) {
843  WRITE_WARNING(TL("invalid combination for ride"));
844  } else {
845  // build ride
846  GNEDemandElement* ride = GNERide::buildRide(myNet, personParent,
847  fromEdge, fromBusStop, fromTrainStop,
848  toEdge, toBusStop, toTrainStop,
849  arrivalPos, lines);
850  // continue depending of undo-redo
851  if (myAllowUndoRedo) {
852  myNet->getViewNet()->getUndoList()->begin(ride, TLF("add % in '%'", ride->getTagStr(), personParent->getID()));
854  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
855  myNet->getViewNet()->getUndoList()->end();
856  } else {
858  // set child references
859  personParent->addChildElement(ride);
860  if (fromEdge) {
861  fromEdge->addChildElement(ride);
862  }
863  if (toEdge) {
864  toEdge->addChildElement(ride);
865  }
866  if (toBusStop) {
867  toBusStop->addChildElement(ride);
868  }
869  if (toTrainStop) {
870  toTrainStop->addChildElement(ride);
871  }
872  ride->incRef("buildRide");
873  }
874  }
875 }
876 
877 
878 void
879 GNERouteHandler::buildContainer(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerParameters) {
880  // first check if ID is duplicated
881  if (!isContainerIdDuplicated(containerParameters.id)) {
882  // obtain type
883  GNEDemandElement* type = getType(containerParameters.vtypeid);
884  if (type == nullptr) {
885  writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerParameters.vtypeid, toString(containerParameters.tag), containerParameters.id));
886  } else {
887  // create container using containerParameters
888  GNEDemandElement* container = new GNEContainer(SUMO_TAG_CONTAINER, myNet, type, containerParameters);
889  if (myAllowUndoRedo) {
890  myNet->getViewNet()->getUndoList()->begin(container, TL("add ") + container->getTagStr() + " '" + container->getID() + "'");
892  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(container, true), true);
893  myNet->getViewNet()->getUndoList()->end();
894  } else {
896  // set container as child of type
897  type->addChildElement(container);
898  container->incRef("buildContainer");
899  }
900  }
901  }
902 }
903 
904 
905 void
906 GNERouteHandler::buildContainerFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerFlowParameters) {
907  // first check if ID is duplicated
908  if (!isContainerIdDuplicated(containerFlowParameters.id)) {
909  // obtain type
910  GNEDemandElement* type = getType(containerFlowParameters.vtypeid);
911  if (type == nullptr) {
912  writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerFlowParameters.vtypeid, toString(containerFlowParameters.tag), containerFlowParameters.id));
913  } else {
914  // create containerFlow using containerFlowParameters
915  GNEDemandElement* containerFlow = new GNEContainer(SUMO_TAG_CONTAINERFLOW, myNet, type, containerFlowParameters);
916  if (myAllowUndoRedo) {
917  myNet->getViewNet()->getUndoList()->begin(containerFlow, TL("add ") + containerFlow->getTagStr() + " '" + containerFlow->getID() + "'");
919  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(containerFlow, true), true);
920  myNet->getViewNet()->getUndoList()->end();
921  } else {
923  // set containerFlow as child of type
924  type->addChildElement(containerFlow);
925  containerFlow->incRef("buildContainerFlow");
926  }
927  }
928  }
929 }
930 
931 
932 void
933 GNERouteHandler::buildTransport(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& fromContainerStopID,
934  const std::string& toEdgeID, const std::string& toContainerStopID, const std::vector<std::string>& /* lines */, const double arrivalPos) {
935  // first parse parents
936  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
937  GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
938  GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
939  GNEAdditional* fromContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, fromContainerStopID, false);
940  GNEAdditional* toContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, toContainerStopID, false);
941  // check if overwritte previous elements
942  if (getPreviousPlanEdge(sumoBaseObject)) {
943  fromEdge = getPreviousPlanEdge(sumoBaseObject);
944  }
945  if (getPreviousPlanContainerStop(sumoBaseObject)) {
946  fromContainerStop = getPreviousPlanContainerStop(sumoBaseObject);
947  }
948  // check conditions
949  if (containerParent == nullptr) {
950  WRITE_WARNING(TL("invalid container parent"));
951  } else if (GNETransport::getTransportTagIcon(fromEdge, toEdge, fromContainerStop, toContainerStop).first == SUMO_TAG_NOTHING) {
952  WRITE_WARNING(TL("invalid combination for personTrip"));
953  } else {
954  // build transport
955  GNEDemandElement* transport = GNETransport::buildTransport(myNet, containerParent, fromEdge, fromContainerStop,
956  toEdge, toContainerStop, arrivalPos);
957  // continue depending of undo-redo
958  if (myAllowUndoRedo) {
959  myNet->getViewNet()->getUndoList()->begin(transport, TLF("add % in '%'", transport->getTagStr(), containerParent->getID()));
961  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
962  myNet->getViewNet()->getUndoList()->end();
963  } else {
965  // set child references
966  containerParent->addChildElement(transport);
967  if (fromEdge) {
968  fromEdge->addChildElement(transport);
969  }
970  if (toEdge) {
971  toEdge->addChildElement(transport);
972  }
973  if (fromContainerStop) {
974  fromContainerStop->addChildElement(transport);
975  }
976  if (toContainerStop) {
977  toContainerStop->addChildElement(transport);
978  }
979  transport->incRef("buildTransport");
980  }
981  }
982 }
983 
984 
985 void
986 GNERouteHandler::buildTranship(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& fromContainerStopID,
987  const std::string& toEdgeID, const std::string& toContainerStopID, const std::vector<std::string>& edgeIDs, const double speed,
988  const double departPosition, const double arrivalPosition) {
989  // first parse parents
990  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
991  GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
992  GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
993  GNEAdditional* fromContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, fromContainerStopID, false);
994  GNEAdditional* toContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, toContainerStopID, false);
995  std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_WALK, edgeIDs);
996  // avoid consecutive duplicated edges
997  edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
998  // check if overwritte previous elements
999  if (getPreviousPlanEdge(sumoBaseObject)) {
1000  fromEdge = getPreviousPlanEdge(sumoBaseObject);
1001  }
1002  if (getPreviousPlanContainerStop(sumoBaseObject)) {
1003  fromContainerStop = getPreviousPlanContainerStop(sumoBaseObject);
1004  }
1005  // check conditions
1006  if (containerParent == nullptr) {
1007  WRITE_WARNING(TL("invalid container parent"));
1008  } else if (GNETranship::getTranshipTagIcon(edges, fromEdge, toEdge, fromContainerStop, toContainerStop).first == SUMO_TAG_NOTHING) {
1009  WRITE_WARNING(TL("invalid combination for personTrip"));
1010  } else {
1011  // build tranship
1012  GNEDemandElement* tranship = GNETranship::buildTranship(myNet, containerParent, fromEdge, fromContainerStop, toEdge,
1013  toContainerStop, edges, departPosition, arrivalPosition, speed);
1014  // continue depending of undo-redo
1015  if (myAllowUndoRedo) {
1016  myNet->getViewNet()->getUndoList()->begin(tranship, TLF("add % in '%'", tranship->getTagStr(), containerParent->getID()));
1018  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
1019  myNet->getViewNet()->getUndoList()->end();
1020  } else {
1022  // set child references
1023  containerParent->addChildElement(tranship);
1024  if (fromEdge) {
1025  fromEdge->addChildElement(tranship);
1026  }
1027  if (toEdge) {
1028  toEdge->addChildElement(tranship);
1029  }
1030  if (fromContainerStop) {
1031  fromContainerStop->addChildElement(tranship);
1032  }
1033  if (toContainerStop) {
1034  toContainerStop->addChildElement(tranship);
1035  }
1036  for (const auto& edge : edges) {
1037  edge->addChildElement(tranship);
1038  }
1039  tranship->incRef("buildTranship");
1040  }
1041  }
1042 }
1043 
1044 
1045 void
1046 GNERouteHandler::buildPersonStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const std::string& busStopID,
1047  const std::string& trainStopID, const double endPos, const SUMOTime duration, const SUMOTime until,
1048  const std::string& actType, const bool friendlyPos, const int parameterSet) {
1049  // parse parents
1050  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
1051  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1053  GNEAdditional* trainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, trainStopID, false);
1054  // check conditions
1055  if (personParent == nullptr) {
1056  WRITE_WARNING(TL("invalid person parent"));
1057  } else if (GNETranship::getPersonStopTagIcon(edge, busStop, trainStop).first == SUMO_TAG_NOTHING) {
1058  WRITE_WARNING(TL("invalid combination for person stop"));
1059  } else {
1060  // build person stop
1061  GNEDemandElement* stopPlan = GNEStopPlan::buildPersonStopPlan(myNet, personParent, edge, busStop, trainStop,
1062  endPos, duration, until, actType, friendlyPos, parameterSet);
1063  // continue depending of undo-redo
1064  if (myAllowUndoRedo) {
1065  myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), personParent->getID()));
1067  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
1068  myNet->getViewNet()->getUndoList()->end();
1069  } else {
1071  // set child references
1072  personParent->addChildElement(stopPlan);
1073  if (edge) {
1074  edge->addChildElement(stopPlan);
1075  }
1076  if (busStop) {
1077  busStop->addChildElement(stopPlan);
1078  }
1079  if (trainStop) {
1080  trainStop->addChildElement(stopPlan);
1081  }
1082  stopPlan->incRef("buildPersonStop");
1083  }
1084  }
1085 }
1086 
1087 
1088 void
1089 GNERouteHandler::buildContainerStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID,
1090  const std::string& containerStopID, const double endPos, const SUMOTime duration,
1091  const SUMOTime until, const std::string& actType, const bool friendlyPos, const int parameterSet) {
1092  // parse parents
1093  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1094  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1095  GNEAdditional* containerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, containerStopID, false);
1096  // check conditions
1097  if (containerParent == nullptr) {
1098  WRITE_WARNING(TL("invalid container parent"));
1099  } else if (GNETranship::getContainerStopTagIcon(edge, containerStop).first == SUMO_TAG_NOTHING) {
1100  WRITE_WARNING(TL("invalid combination for containerStop"));
1101  } else {
1102  // build container stop
1103  GNEDemandElement* stopPlan = GNEStopPlan::buildContainerStopPlan(myNet, containerParent, edge, containerStop,
1104  endPos, duration, until, actType, friendlyPos, parameterSet);
1105  // continue depending of undo-redo
1106  if (myAllowUndoRedo) {
1107  myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), containerParent->getID()));
1109  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
1110  myNet->getViewNet()->getUndoList()->end();
1111  } else {
1113  // set child references
1114  containerParent->addChildElement(stopPlan);
1115  if (edge) {
1116  edge->addChildElement(stopPlan);
1117  }
1118  if (containerStop) {
1119  containerStop->addChildElement(stopPlan);
1120  }
1121  stopPlan->incRef("buildContainerStop");
1122  }
1123  }
1124 }
1125 
1126 
1127 void
1129  // get obj parent
1130  const auto objParent = sumoBaseObject->getParentSumoBaseObject();
1131  // continue depending of objParent
1132  if (objParent == nullptr) {
1133  WRITE_WARNING(TL("Stops needs a parent"));
1134  } else if ((objParent->getTag() == SUMO_TAG_PERSON) || (objParent->getTag() == SUMO_TAG_PERSONFLOW)) {
1135  buildPersonStop(sumoBaseObject, stopParameters.edge, stopParameters.busstop, stopParameters.busstop, stopParameters.endPos,
1136  stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
1137  } else if ((objParent->getTag() == SUMO_TAG_CONTAINER) || (objParent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
1138  buildContainerStop(sumoBaseObject, stopParameters.edge, stopParameters.containerstop, stopParameters.endPos,
1139  stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
1140  } else {
1141  // get vehicle tag
1142  SumoXMLTag vehicleTag = objParent->getTag();
1143  if (vehicleTag == SUMO_TAG_VEHICLE) {
1144  // check if vehicle is placed over route or with embedded route
1145  if (!objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
1146  vehicleTag = GNE_TAG_VEHICLE_WITHROUTE;
1147  }
1148  } else if (vehicleTag == SUMO_TAG_FLOW) {
1149  if (objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
1150  vehicleTag = GNE_TAG_FLOW_ROUTE;
1151  } else if (objParent->hasStringAttribute(SUMO_ATTR_FROM) && objParent->hasStringAttribute(SUMO_ATTR_TO)) {
1152  vehicleTag = SUMO_TAG_FLOW;
1153  } else {
1154  vehicleTag = GNE_TAG_FLOW_WITHROUTE;
1155  }
1156  }
1157  // get stop parent
1158  GNEDemandElement* stopParent = myNet->getAttributeCarriers()->retrieveDemandElement(vehicleTag, objParent->getStringAttribute(SUMO_ATTR_ID), false);
1159  // check if stopParent exist
1160  if (stopParent) {
1161  // flag for waypoint (is like a stop, but with extra attribute speed)
1162  bool waypoint = false;
1163  // avoid waypoints for person and containers
1164  if (!stopParent->getTagProperty().isPerson() && !stopParent->getTagProperty().isContainer()) {
1165  waypoint = (sumoBaseObject->getStopParameter().parametersSet & STOP_SPEED_SET) || (sumoBaseObject->getStopParameter().speed > 0);
1166  }
1167  // declare pointers to parent elements
1168  GNEAdditional* stoppingPlace = nullptr;
1169  GNELane* lane = nullptr;
1170  GNEEdge* edge = nullptr;
1171  // declare stopTagType
1172  SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
1173  bool validParentDemandElement = true;
1174  // check conditions
1175  if (stopParameters.busstop.size() > 0) {
1176  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
1177  stopTagType = waypoint ? GNE_TAG_WAYPOINT_BUSSTOP : GNE_TAG_STOP_BUSSTOP;
1178  // check if is a train stop
1179  if (stoppingPlace == nullptr) {
1180  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, stopParameters.busstop, false);
1181  stopTagType = waypoint ? GNE_TAG_WAYPOINT_TRAINSTOP : GNE_TAG_STOP_TRAINSTOP;
1182  }
1183  // containers cannot stops in busStops
1184  if (stopParent->getTagProperty().isContainer()) {
1185  writeError(TL("Containers don't support stops at busStops or trainStops"));
1186  validParentDemandElement = false;
1187  }
1188  } else if (stopParameters.containerstop.size() > 0) {
1189  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
1191  // persons cannot stops in containerStops
1192  if (stopParent->getTagProperty().isPerson()) {
1193  writeError(TL("Persons don't support stops at containerStops"));
1194  validParentDemandElement = false;
1195  }
1196  } else if (stopParameters.chargingStation.size() > 0) {
1197  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, stopParameters.chargingStation, false);
1199  // check person and containers
1200  if (stopParent->getTagProperty().isPerson()) {
1201  writeError(TL("Persons don't support stops at chargingStations"));
1202  validParentDemandElement = false;
1203  } else if (stopParent->getTagProperty().isContainer()) {
1204  writeError(TL("Containers don't support stops at chargingStations"));
1205  validParentDemandElement = false;
1206  }
1207  } else if (stopParameters.parkingarea.size() > 0) {
1208  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
1209  stopTagType = waypoint ? GNE_TAG_WAYPOINT_PARKINGAREA : GNE_TAG_STOP_PARKINGAREA;
1210  // check person and containers
1211  if (stopParent->getTagProperty().isPerson()) {
1212  writeError(TL("Persons don't support stops at parkingAreas"));
1213  validParentDemandElement = false;
1214  } else if (stopParent->getTagProperty().isContainer()) {
1215  writeError(TL("Containers don't support stops at parkingAreas"));
1216  validParentDemandElement = false;
1217  }
1218  } else if (stopParameters.lane.size() > 0) {
1219  lane = myNet->getAttributeCarriers()->retrieveLane(stopParameters.lane, false);
1220  stopTagType = waypoint ? GNE_TAG_WAYPOINT_LANE : GNE_TAG_STOP_LANE;
1221  } else if (stopParameters.edge.size() > 0) {
1222  edge = myNet->getAttributeCarriers()->retrieveEdge(stopParameters.edge, false);
1223  // check vehicles
1224  if (stopParent->getTagProperty().isVehicle()) {
1225  writeError(TL("vehicles don't support stops at edges"));
1226  validParentDemandElement = false;
1227  }
1228  }
1229  // overwrite lane with edge parent if we're handling a personStop
1230  if (lane && (stopParent->getTagProperty().isPerson() || stopParent->getTagProperty().isContainer())) {
1231  edge = lane->getParentEdge();
1232  lane = nullptr;
1233  }
1234  // first check that parent is valid
1235  if (validParentDemandElement) {
1236  // check if values are correct
1237  if (stoppingPlace && lane && edge) {
1238  writeError(TL("A stop must be defined either over a stoppingPlace, a edge or a lane"));
1239  } else if (!stoppingPlace && !lane && !edge) {
1240  writeError(TL("A stop requires only a stoppingPlace, edge or lane"));
1241  } else if (stoppingPlace) {
1242  // create stop using stopParameters and stoppingPlace
1243  GNEDemandElement* stop = nullptr;
1244  if (stopParent->getTagProperty().isPerson()) {
1245  if (stoppingPlace->getTagProperty().getTag() == SUMO_TAG_BUS_STOP) {
1246  stop = new GNEStop(GNE_TAG_STOPPERSON_BUSSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1247  } else {
1248  stop = new GNEStop(GNE_TAG_STOPPERSON_TRAINSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1249  }
1250  } else if (stopParent->getTagProperty().isContainer()) {
1251  stop = new GNEStop(GNE_TAG_STOPCONTAINER_CONTAINERSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1252  } else {
1253  stop = new GNEStop(stopTagType, myNet, stopParent, stoppingPlace, stopParameters);
1254  }
1255  // add it depending of undoDemandElements
1256  if (myAllowUndoRedo) {
1257  myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1259  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1260  myNet->getViewNet()->getUndoList()->end();
1261  } else {
1263  stoppingPlace->addChildElement(stop);
1264  stopParent->addChildElement(stop);
1265  stop->incRef("buildStoppingPlaceStop");
1266  }
1267  } else if (lane) {
1268  // create stop using stopParameters and lane (only for vehicles)
1269  GNEDemandElement* stop = new GNEStop(stopTagType, myNet, stopParent, lane, stopParameters);
1270  // add it depending of undoDemandElements
1271  if (myAllowUndoRedo) {
1272  myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1274  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1275  myNet->getViewNet()->getUndoList()->end();
1276  } else {
1278  lane->addChildElement(stop);
1279  stopParent->addChildElement(stop);
1280  stop->incRef("buildLaneStop");
1281  }
1282  }
1283  }
1284  }
1285  }
1286 }
1287 
1288 
1289 bool
1291  GNEAttributesCreator* personPlanAttributes, GNEPlanCreator* planCreator,
1292  const bool centerAfterCreation) {
1293  // first check if person is valid
1294  if (personParent == nullptr) {
1295  return false;
1296  }
1297  // clear and set person object
1298  myPlanObject->clear();
1299  myPlanObject->setTag(personParent->getTagProperty().getTag());
1301  // declare personPlan object
1303  // get person plan attributes
1304  personPlanAttributes->getAttributesAndValues(personPlanObject, true);
1305  // get attributes
1306  const std::vector<std::string> types = personPlanObject->hasStringListAttribute(SUMO_ATTR_VTYPES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_VTYPES) : std::vector<std::string>();
1307  const std::vector<std::string> modes = personPlanObject->hasStringListAttribute(SUMO_ATTR_MODES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_MODES) : std::vector<std::string>();
1308  const std::vector<std::string> lines = personPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_LINES) : std::vector<std::string>();
1309  const double arrivalPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) : -1;
1310  const double endPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) : planCreator->getClickedPositionOverLane();
1311  const SUMOTime duration = personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? personPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) : 0;
1312  const SUMOTime until = personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? personPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) : 0;
1313  const std::string actType = personPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? personPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1314  const bool friendlyPos = personPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? personPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) : false;
1315  // get consecutive edges
1316  const auto consecutiveEdges = planCreator->getConsecutiveEdgeIDs();
1317  // get edges
1318  GNEEdge* fromEdge = planCreator->getFromEdge();
1319  GNEEdge* toEdge = planCreator->getToEdge();
1320  // get junctions
1321  GNEJunction* fromJunction = planCreator->getFromJunction();
1322  GNEJunction* toJunction = planCreator->getToJunction();
1323  // get TAZs
1324  GNEAdditional* fromTAZ = planCreator->getFromTAZ();
1325  GNEAdditional* toTAZ = planCreator->getToTAZ();
1326  // get busStops
1327  GNEAdditional* fromBusStop = planCreator->getFromBusStop();
1328  GNEAdditional* toBusStop = planCreator->getToBusStop();
1329  // get trainStops
1330  GNEAdditional* fromTrainStop = planCreator->getFromTrainStop();
1331  GNEAdditional* toTrainStop = planCreator->getToTrainStop();
1332  // get route
1333  GNEDemandElement* route = planCreator->getRoute();
1334  // get edge
1335  GNEEdge* edge = planCreator->getEdge();
1336  // get busStop
1337  GNEAdditional* busStop = planCreator->getBusStop();
1338  // get trainStop
1339  GNEAdditional* trainStop = planCreator->getTrainStop();
1340  // special case for elements with from-to edge
1341  if (fromEdge && !toEdge && !fromTAZ && !toTAZ && !fromJunction && !toJunction &&
1342  !fromBusStop && !toBusStop && !fromTrainStop && !toTrainStop &&
1343  consecutiveEdges.empty() && !route) {
1344  toEdge = fromEdge;
1345  }
1346  // create plans depending of elements
1347  if (consecutiveEdges.size() > 0) {
1348  // consecutive edges
1349  personPlanObject->setTag(GNE_TAG_WALK_EDGES);
1350  buildWalk(personPlanObject,
1351  "", "", "", "", "",
1352  "", "", "", "", "",
1353  consecutiveEdges, "", arrivalPos);
1354  } else if (route) {
1355  // single route
1356  personPlanObject->setTag(GNE_TAG_WALK_ROUTE);
1357  buildWalk(personPlanObject,
1358  "", "", "", "", "",
1359  "", "", "", "", "",
1360  {}, route->getID(), arrivalPos);
1361  } else if (planTemplate->getTagProperty().isPlanWalk()) {
1362  // set walk tag
1363  personPlanObject->setTag(GNEDemandElementPlan::getWalkTagIcon({}, route,
1364  fromEdge, toEdge, fromTAZ, toTAZ, fromJunction, toJunction,
1365  fromBusStop, toBusStop, fromTrainStop, toTrainStop).first);
1366  // from edges
1367  if (fromEdge && toEdge) {
1368  // walk: edge->edge
1369  buildWalk(personPlanObject,
1370  fromEdge->getID(), "", "", "", "",
1371  toEdge->getID(), "", "", "", "",
1372  {}, "", arrivalPos);
1373  } else if (fromEdge && toTAZ) {
1374  // walk: edge->TAZ
1375  buildWalk(personPlanObject,
1376  fromEdge->getID(), "", "", "", "",
1377  "", toTAZ->getID(), "", "", "",
1378  {}, "", arrivalPos);
1379  } else if (fromEdge && toJunction) {
1380  // walk: edge->edge
1381  buildWalk(personPlanObject,
1382  fromEdge->getID(), "", "", "", "",
1383  "", "", toJunction->getID(), "", "",
1384  {}, "", arrivalPos);
1385  } else if (fromEdge && toBusStop) {
1386  // walk: edge->busStop
1387  buildWalk(personPlanObject,
1388  fromEdge->getID(), "", "", "", "",
1389  "", "", "", toBusStop->getID(), "",
1390  {}, "", arrivalPos);
1391  } else if (fromEdge && toTrainStop) {
1392  // walk: edge->trainStop
1393  buildWalk(personPlanObject,
1394  fromEdge->getID(), "", "", "", "",
1395  "", "", "", "", toTrainStop->getID(),
1396  {}, "", arrivalPos);
1397  // from TAZs
1398  } else if (fromTAZ && toEdge) {
1399  // walk: edge->edge
1400  buildWalk(personPlanObject,
1401  "", fromTAZ->getID(), "", "", "",
1402  toEdge->getID(), "", "", "", "",
1403  {}, "", arrivalPos);
1404  } else if (fromTAZ && toTAZ) {
1405  // walk: edge->TAZ
1406  buildWalk(personPlanObject,
1407  "", fromTAZ->getID(), "", "", "",
1408  "", toTAZ->getID(), "", "", "",
1409  {}, "", arrivalPos);
1410  } else if (fromTAZ && toJunction) {
1411  // walk: edge->edge
1412  buildWalk(personPlanObject,
1413  "", fromTAZ->getID(), "", "", "",
1414  "", "", toJunction->getID(), "", "",
1415  {}, "", arrivalPos);
1416  } else if (fromTAZ && toBusStop) {
1417  // walk: edge->busStop
1418  buildWalk(personPlanObject,
1419  "", fromTAZ->getID(), "", "", "",
1420  "", "", "", toBusStop->getID(), "",
1421  {}, "", arrivalPos);
1422  } else if (fromTAZ && toTrainStop) {
1423  // walk: edge->trainStop
1424  buildWalk(personPlanObject,
1425  "", fromTAZ->getID(), "", "", "",
1426  "", "", "", "", toTrainStop->getID(),
1427  {}, "", arrivalPos);
1428  // from junction
1429  } else if (fromJunction && toEdge) {
1430  // walk: edge->edge
1431  buildWalk(personPlanObject,
1432  "", "", fromJunction->getID(), "", "",
1433  toEdge->getID(), "", "", "", "",
1434  {}, "", arrivalPos);
1435  } else if (fromJunction && toTAZ) {
1436  // walk: edge->TAZ
1437  buildWalk(personPlanObject,
1438  "", "", fromJunction->getID(), "", "",
1439  "", toTAZ->getID(), "", "", "",
1440  {}, "", arrivalPos);
1441  } else if (fromJunction && toJunction) {
1442  // walk: edge->edge
1443  buildWalk(personPlanObject,
1444  "", "", fromJunction->getID(), "", "",
1445  "", "", toJunction->getID(), "", "",
1446  {}, "", arrivalPos);
1447  } else if (fromJunction && toBusStop) {
1448  // walk: edge->busStop
1449  buildWalk(personPlanObject,
1450  "", "", fromJunction->getID(), "", "",
1451  "", "", "", toBusStop->getID(), "",
1452  {}, "", arrivalPos);
1453  } else if (fromJunction && toTrainStop) {
1454  // walk: edge->trainStop
1455  buildWalk(personPlanObject,
1456  "", "", fromJunction->getID(), "", "",
1457  "", "", "", "", toTrainStop->getID(),
1458  {}, "", arrivalPos);
1459  // from busStop
1460  } else if (fromBusStop && toEdge) {
1461  // walk: edge->edge
1462  buildWalk(personPlanObject,
1463  "", "", "", fromBusStop->getID(), "",
1464  toEdge->getID(), "", "", "", "",
1465  {}, "", arrivalPos);
1466  } else if (fromBusStop && toTAZ) {
1467  // walk: edge->TAZ
1468  buildWalk(personPlanObject,
1469  "", "", "", fromBusStop->getID(), "",
1470  "", toTAZ->getID(), "", "", "",
1471  {}, "", arrivalPos);
1472  } else if (fromBusStop && toJunction) {
1473  // walk: edge->edge
1474  buildWalk(personPlanObject,
1475  "", "", "", fromBusStop->getID(), "",
1476  "", "", toJunction->getID(), "", "",
1477  {}, "", arrivalPos);
1478  } else if (fromBusStop && toBusStop) {
1479  // walk: edge->busStop
1480  buildWalk(personPlanObject,
1481  "", "", "", fromBusStop->getID(), "",
1482  "", "", "", toBusStop->getID(), "",
1483  {}, "", arrivalPos);
1484  } else if (fromBusStop && toTrainStop) {
1485  // walk: edge->trainStop
1486  buildWalk(personPlanObject,
1487  "", "", "", fromBusStop->getID(), "",
1488  "", "", "", "", toTrainStop->getID(),
1489  {}, "", arrivalPos);
1490  // from trainStop
1491  } else if (fromTrainStop && toEdge) {
1492  // walk: edge->edge
1493  buildWalk(personPlanObject,
1494  "", "", "", "", fromTrainStop->getID(),
1495  toEdge->getID(), "", "", "", "",
1496  {}, "", arrivalPos);
1497  } else if (fromTrainStop && toTAZ) {
1498  // walk: edge->TAZ
1499  buildWalk(personPlanObject,
1500  "", "", "", "", fromTrainStop->getID(),
1501  "", toTAZ->getID(), "", "", "",
1502  {}, "", arrivalPos);
1503  } else if (fromTrainStop && toJunction) {
1504  // walk: edge->edge
1505  buildWalk(personPlanObject,
1506  "", "", "", "", fromTrainStop->getID(),
1507  "", "", toJunction->getID(), "", "",
1508  {}, "", arrivalPos);
1509  } else if (fromTrainStop && toBusStop) {
1510  // walk: edge->busStop
1511  buildWalk(personPlanObject,
1512  "", "", "", "", fromTrainStop->getID(),
1513  "", "", "", toBusStop->getID(), "",
1514  {}, "", arrivalPos);
1515  } else if (fromTrainStop && toTrainStop) {
1516  // walk: edge->trainStop
1517  buildWalk(personPlanObject,
1518  "", "", "", "", fromTrainStop->getID(),
1519  "", "", "", "", toTrainStop->getID(),
1520  {}, "", arrivalPos);
1521  }
1522  } else if (planTemplate->getTagProperty().isPersonTrip()) {
1523  // set person trip tag
1524  personPlanObject->setTag(GNEDemandElementPlan::getPersonTripTagIcon(fromEdge, toEdge,
1525  fromTAZ, toTAZ, fromJunction, toJunction, fromBusStop, toBusStop,
1526  fromTrainStop, toTrainStop).first);
1527  // from edges
1528  if (fromEdge && toEdge) {
1529  // personTrip: edge->edge
1530  buildPersonTrip(personPlanObject,
1531  fromEdge->getID(), "", "", "", "",
1532  toEdge->getID(), "", "", "", "",
1533  arrivalPos, types, modes, lines);
1534  } else if (fromEdge && toTAZ) {
1535  // personTrip: edge->TAZ
1536  buildPersonTrip(personPlanObject,
1537  fromEdge->getID(), "", "", "", "",
1538  "", toTAZ->getID(), "", "", "",
1539  arrivalPos, types, modes, lines);
1540  } else if (fromEdge && toJunction) {
1541  // personTrip: edge->edge
1542  buildPersonTrip(personPlanObject,
1543  fromEdge->getID(), "", "", "", "",
1544  "", "", toJunction->getID(), "", "",
1545  arrivalPos, types, modes, lines);
1546  } else if (fromEdge && toBusStop) {
1547  // personTrip: edge->busStop
1548  buildPersonTrip(personPlanObject,
1549  fromEdge->getID(), "", "", "", "",
1550  "", "", "", toBusStop->getID(), "",
1551  arrivalPos, types, modes, lines);
1552  } else if (fromEdge && toTrainStop) {
1553  // personTrip: edge->trainStop
1554  buildPersonTrip(personPlanObject,
1555  fromEdge->getID(), "", "", "", "",
1556  "", "", "", "", toTrainStop->getID(),
1557  arrivalPos, types, modes, lines);
1558  // from TAZs
1559  } else if (fromTAZ && toEdge) {
1560  // personTrip: edge->edge
1561  buildPersonTrip(personPlanObject,
1562  "", fromTAZ->getID(), "", "", "",
1563  toEdge->getID(), "", "", "", "",
1564  arrivalPos, types, modes, lines);
1565  } else if (fromTAZ && toTAZ) {
1566  // personTrip: edge->TAZ
1567  buildPersonTrip(personPlanObject,
1568  "", fromTAZ->getID(), "", "", "",
1569  "", toTAZ->getID(), "", "", "",
1570  arrivalPos, types, modes, lines);
1571  } else if (fromTAZ && toJunction) {
1572  // personTrip: edge->edge
1573  buildPersonTrip(personPlanObject,
1574  "", fromTAZ->getID(), "", "", "",
1575  "", "", toJunction->getID(), "", "",
1576  arrivalPos, types, modes, lines);
1577  } else if (fromTAZ && toBusStop) {
1578  // personTrip: edge->busStop
1579  buildPersonTrip(personPlanObject,
1580  "", fromTAZ->getID(), "", "", "",
1581  "", "", "", toBusStop->getID(), "",
1582  arrivalPos, types, modes, lines);
1583  } else if (fromTAZ && toTrainStop) {
1584  // personTrip: edge->trainStop
1585  buildPersonTrip(personPlanObject,
1586  "", fromTAZ->getID(), "", "", "",
1587  "", "", "", "", toTrainStop->getID(),
1588  arrivalPos, types, modes, lines);
1589  // from junction
1590  } else if (fromJunction && toEdge) {
1591  // personTrip: edge->edge
1592  buildPersonTrip(personPlanObject,
1593  "", "", fromJunction->getID(), "", "",
1594  toEdge->getID(), "", "", "", "",
1595  arrivalPos, types, modes, lines);
1596  } else if (fromJunction && toTAZ) {
1597  // personTrip: edge->TAZ
1598  buildPersonTrip(personPlanObject,
1599  "", "", fromJunction->getID(), "", "",
1600  "", toTAZ->getID(), "", "", "",
1601  arrivalPos, types, modes, lines);
1602  } else if (fromJunction && toJunction) {
1603  // personTrip: edge->edge
1604  buildPersonTrip(personPlanObject,
1605  "", "", fromJunction->getID(), "", "",
1606  "", "", toJunction->getID(), "", "",
1607  arrivalPos, types, modes, lines);
1608  } else if (fromJunction && toBusStop) {
1609  // personTrip: edge->busStop
1610  buildPersonTrip(personPlanObject,
1611  "", "", fromJunction->getID(), "", "",
1612  "", "", "", toBusStop->getID(), "",
1613  arrivalPos, types, modes, lines);
1614  } else if (fromJunction && toTrainStop) {
1615  // personTrip: edge->trainStop
1616  buildPersonTrip(personPlanObject,
1617  "", "", fromJunction->getID(), "", "",
1618  "", "", "", "", toTrainStop->getID(),
1619  arrivalPos, types, modes, lines);
1620  // from busStop
1621  } else if (fromBusStop && toEdge) {
1622  // personTrip: edge->edge
1623  buildPersonTrip(personPlanObject,
1624  "", "", "", fromBusStop->getID(), "",
1625  toEdge->getID(), "", "", "", "",
1626  arrivalPos, types, modes, lines);
1627  } else if (fromBusStop && toTAZ) {
1628  // personTrip: edge->TAZ
1629  buildPersonTrip(personPlanObject,
1630  "", "", "", fromBusStop->getID(), "",
1631  "", toTAZ->getID(), "", "", "",
1632  arrivalPos, types, modes, lines);
1633  } else if (fromBusStop && toJunction) {
1634  // personTrip: edge->edge
1635  buildPersonTrip(personPlanObject,
1636  "", "", "", fromBusStop->getID(), "",
1637  "", "", toJunction->getID(), "", "",
1638  arrivalPos, types, modes, lines);
1639  } else if (fromBusStop && toBusStop) {
1640  // personTrip: edge->busStop
1641  buildPersonTrip(personPlanObject,
1642  "", "", "", fromBusStop->getID(), "",
1643  "", "", "", toBusStop->getID(), "",
1644  arrivalPos, types, modes, lines);
1645  } else if (fromBusStop && toTrainStop) {
1646  // personTrip: edge->trainStop
1647  buildPersonTrip(personPlanObject,
1648  "", "", "", fromBusStop->getID(), "",
1649  "", "", "", "", toTrainStop->getID(),
1650  arrivalPos, types, modes, lines);
1651  // from trainStop
1652  } else if (fromTrainStop && toEdge) {
1653  // personTrip: edge->edge
1654  buildPersonTrip(personPlanObject,
1655  "", "", "", "", fromTrainStop->getID(),
1656  toEdge->getID(), "", "", "", "",
1657  arrivalPos, types, modes, lines);
1658  } else if (fromTrainStop && toTAZ) {
1659  // personTrip: edge->TAZ
1660  buildPersonTrip(personPlanObject,
1661  "", "", "", "", fromTrainStop->getID(),
1662  "", toTAZ->getID(), "", "", "",
1663  arrivalPos, types, modes, lines);
1664  } else if (fromTrainStop && toJunction) {
1665  // personTrip: edge->edge
1666  buildPersonTrip(personPlanObject,
1667  "", "", "", "", fromTrainStop->getID(),
1668  "", "", toJunction->getID(), "", "",
1669  arrivalPos, types, modes, lines);
1670  } else if (fromTrainStop && toBusStop) {
1671  // personTrip: edge->busStop
1672  buildPersonTrip(personPlanObject,
1673  "", "", "", "", fromTrainStop->getID(),
1674  "", "", "", toBusStop->getID(), "",
1675  arrivalPos, types, modes, lines);
1676  } else if (fromTrainStop && toTrainStop) {
1677  // personTrip: edge->trainStop
1678  buildPersonTrip(personPlanObject,
1679  "", "", "", "", fromTrainStop->getID(),
1680  "", "", "", "", toTrainStop->getID(),
1681  arrivalPos, types, modes, lines);
1682  }
1683  } else if (planTemplate->getTagProperty().isPlanRide()) {
1684  // set ride tag
1685  personPlanObject->setTag(GNEDemandElementPlan::getRideTagIcon(fromEdge, toEdge,
1686  fromBusStop, toBusStop, fromTrainStop, toTrainStop).first);
1687  // from edges
1688  if (fromEdge && toEdge) {
1689  // ride: edge->edge
1690  buildRide(personPlanObject,
1691  fromEdge->getID(), "", "",
1692  toEdge->getID(), "", "",
1693  arrivalPos, lines);
1694  } else if (fromEdge && toBusStop) {
1695  // ride: edge->busStop
1696  buildRide(personPlanObject,
1697  fromEdge->getID(), "", "",
1698  "", toBusStop->getID(), "",
1699  arrivalPos, lines);
1700  } else if (fromEdge && toTrainStop) {
1701  // ride: edge->trainStop
1702  buildRide(personPlanObject,
1703  fromEdge->getID(), "", "",
1704  "", "", toTrainStop->getID(),
1705  arrivalPos, lines);
1706  // from busStop
1707  } else if (fromBusStop && toEdge) {
1708  // ride: edge->edge
1709  buildRide(personPlanObject,
1710  "", fromBusStop->getID(), "",
1711  toEdge->getID(), "", "",
1712  arrivalPos, lines);
1713  } else if (fromBusStop && toBusStop) {
1714  // ride: edge->busStop
1715  buildRide(personPlanObject,
1716  "", fromBusStop->getID(), "",
1717  "", toBusStop->getID(), "",
1718  arrivalPos, lines);
1719  } else if (fromBusStop && toTrainStop) {
1720  // ride: edge->trainStop
1721  buildRide(personPlanObject,
1722  "", fromBusStop->getID(), "",
1723  "", "", toTrainStop->getID(),
1724  arrivalPos, lines);
1725  // from trainStop
1726  } else if (fromTrainStop && toEdge) {
1727  // ride: edge->edge
1728  buildRide(personPlanObject,
1729  "", "", fromTrainStop->getID(),
1730  toEdge->getID(), "", "",
1731  arrivalPos, lines);
1732  } else if (fromTrainStop && toBusStop) {
1733  // ride: edge->busStop
1734  buildRide(personPlanObject,
1735  "", "", fromTrainStop->getID(),
1736  "", toBusStop->getID(), "",
1737  arrivalPos, lines);
1738  } else if (fromTrainStop && toTrainStop) {
1739  // ride: edge->trainStop
1740  buildRide(personPlanObject,
1741  "", "", fromTrainStop->getID(),
1742  "", "", toTrainStop->getID(),
1743  arrivalPos, lines);
1744  }
1745  } else if (planTemplate->getTagProperty().isPlanStopPerson()) {
1746  // set ride tag
1747  personPlanObject->setTag(GNEDemandElementPlan::getPersonStopTagIcon(edge, busStop, trainStop).first);
1748  // set parameters
1749  int parameterSet = 0;
1750  if (personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1751  parameterSet |= STOP_DURATION_SET;
1752  }
1753  if (personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1754  parameterSet |= STOP_UNTIL_SET;
1755  }
1756  // from edges
1757  if (edge) {
1758  buildPersonStop(personPlanObject, edge->getID(), "", "", endPos, duration, until, actType, friendlyPos, parameterSet);
1759  } else if (busStop) {
1760  buildPersonStop(personPlanObject, "", busStop->getID(), "", endPos, duration, until, actType, friendlyPos, parameterSet);
1761  } else if (trainStop) {
1762  buildPersonStop(personPlanObject, "", "", trainStop->getID(), endPos, duration, until, actType, friendlyPos, parameterSet);
1763  }
1764  }
1765  // get person
1766  const auto person = myNet->getAttributeCarriers()->retrieveDemandElement(personPlanObject->getParentSumoBaseObject()->getTag(),
1767  personPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1768  if (person) {
1769  // center view after creation
1770  if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(person->getPositionInView())) {
1771  myNet->getViewNet()->centerTo(person->getPositionInView(), false);
1772  }
1773  }
1774  return true;
1775 }
1776 
1777 
1778 bool
1780  GNEAttributesCreator* containerPlanAttributes, GNEPlanCreator* planCreator,
1781  const bool centerAfterCreation) {
1782  // first check if container is valid
1783  if (containerParent == nullptr) {
1784  return false;
1785  }
1786  // clear and set container object
1787  myPlanObject->clear();
1788  myPlanObject->setTag(containerParent->getTagProperty().getTag());
1789  myPlanObject->addStringAttribute(SUMO_ATTR_ID, containerParent->getID());
1790  // declare containerPlan object
1792  // get container plan attributes
1793  containerPlanAttributes->getAttributesAndValues(containerPlanObject, true);
1794  // get attributes
1795  const double speed = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) : 0;
1796  const std::vector<std::string> lines = containerPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? containerPlanObject->getStringListAttribute(SUMO_ATTR_LINES) : std::vector<std::string>();
1797  const double departPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_DEPARTPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS) : -1;
1798  const double arrivalPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) : -1;
1799  const double endPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) : planCreator->getClickedPositionOverLane();
1800  const SUMOTime duration = containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) : 0;
1801  const SUMOTime until = containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) : 0;
1802  const std::string actType = containerPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? containerPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1803  const bool friendlyPos = containerPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? containerPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) : false;
1804  // get consecutive edges
1805  const auto consecutiveEdges = planCreator->getConsecutiveEdgeIDs();
1806  // get edges
1807  GNEEdge* fromEdge = planCreator->getFromEdge();
1808  GNEEdge* toEdge = planCreator->getToEdge();
1809  // get containerStops
1810  GNEAdditional* fromContainerStop = planCreator->getFromContainerStop();
1811  GNEAdditional* toContainerStop = planCreator->getToContainerStop();
1812  // get edge
1813  GNEEdge* edge = planCreator->getEdge();
1814  // get containerStop
1815  GNEAdditional* containerStop = planCreator->getContainerStop();
1816  // special case for elements with from-to edge
1817  if (fromEdge && !toEdge && !fromContainerStop && !toContainerStop && consecutiveEdges.empty()) {
1818  toEdge = fromEdge;
1819  }
1820  // create plans depending of elements
1821  if (consecutiveEdges.size() > 0) {
1822  // consecutive edges
1823  containerPlanObject->setTag(GNE_TAG_TRANSHIP_EDGES);
1824  buildTranship(containerPlanObject,
1825  "", "",
1826  "", "",
1827  consecutiveEdges, speed, departPos, arrivalPos);
1828  } else if (planTemplate->getTagProperty().isPlanTranship()) {
1829  // set tranship tag
1830  containerPlanObject->setTag(GNEDemandElementPlan::getTranshipTagIcon({},
1831  fromEdge, toEdge, fromContainerStop, toContainerStop).first);
1832  // from edges
1833  if (fromEdge && toEdge) {
1834  // tranship: edge->edge
1835  buildTranship(containerPlanObject,
1836  fromEdge->getID(), "",
1837  toEdge->getID(), "",
1838  {}, speed, departPos, arrivalPos);
1839  } else if (fromEdge && toContainerStop) {
1840  // tranship: edge->containerStop
1841  buildTranship(containerPlanObject,
1842  fromEdge->getID(), "",
1843  "", toContainerStop->getID(),
1844  {}, speed, departPos, arrivalPos);
1845  // from containerStop
1846  } else if (fromContainerStop && toEdge) {
1847  // tranship: edge->edge
1848  buildTranship(containerPlanObject,
1849  "", fromContainerStop->getID(),
1850  toEdge->getID(), "",
1851  {}, speed, departPos, arrivalPos);
1852  } else if (fromContainerStop && toContainerStop) {
1853  // tranship: edge->containerStop
1854  buildTranship(containerPlanObject,
1855  "", fromContainerStop->getID(),
1856  "", toContainerStop->getID(),
1857  {}, speed, departPos, arrivalPos);
1858  }
1859  } else if (planTemplate->getTagProperty().isPlanTransport()) {
1860  // set container trip tag
1861  containerPlanObject->setTag(GNEDemandElementPlan::getTransportTagIcon(fromEdge, toEdge,
1862  fromContainerStop, toContainerStop).first);
1863  // from edges
1864  if (fromEdge && toEdge) {
1865  // containerTrip: edge->edge
1866  buildTransport(containerPlanObject,
1867  fromEdge->getID(), "",
1868  toEdge->getID(), "",
1869  lines, arrivalPos);
1870  } else if (fromEdge && toContainerStop) {
1871  // containerTrip: edge->containerStop
1872  buildTransport(containerPlanObject,
1873  fromEdge->getID(), "",
1874  "", toContainerStop->getID(),
1875  lines, arrivalPos);
1876  // from containerStop
1877  } else if (fromContainerStop && toEdge) {
1878  // containerTrip: edge->edge
1879  buildTransport(containerPlanObject,
1880  "", fromContainerStop->getID(),
1881  toEdge->getID(), "",
1882  lines, arrivalPos);
1883  } else if (fromContainerStop && toContainerStop) {
1884  // containerTrip: edge->containerStop
1885  buildTransport(containerPlanObject,
1886  "", fromContainerStop->getID(),
1887  "", toContainerStop->getID(),
1888  lines, arrivalPos);
1889  }
1890  } else if (planTemplate->getTagProperty().isPlanStopContainer()) {
1891  // set ride tag
1892  containerPlanObject->setTag(GNEDemandElementPlan::getContainerStopTagIcon(edge, containerStop).first);
1893  // set parameters
1894  int parameterSet = 0;
1895  if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1896  parameterSet |= STOP_DURATION_SET;
1897  }
1898  if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1899  parameterSet |= STOP_UNTIL_SET;
1900  }
1901  if (edge) {
1902  buildContainerStop(containerPlanObject, edge->getID(), "", endPos, duration, until, actType, friendlyPos, parameterSet);
1903  } else if (containerStop) {
1904  buildContainerStop(containerPlanObject, "", containerStop->getID(), endPos, duration, until, actType, friendlyPos, parameterSet);
1905  }
1906  }
1907  // get container
1908  const auto container = myNet->getAttributeCarriers()->retrieveDemandElement(containerPlanObject->getParentSumoBaseObject()->getTag(),
1909  containerPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1910  if (container) {
1911  // center view after creation
1912  if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(container->getPositionInView())) {
1913  myNet->getViewNet()->centerTo(container->getPositionInView(), false);
1914  }
1915  }
1916  return true;
1917 }
1918 
1919 
1920 bool
1922  // declare vehicle tags vector
1923  const std::vector<SumoXMLTag> vehicleTags = {SUMO_TAG_VEHICLE, GNE_TAG_VEHICLE_WITHROUTE, SUMO_TAG_TRIP, GNE_TAG_TRIP_TAZS,
1925  };
1926  for (const auto& vehicleTag : vehicleTags) {
1927  if (!checkDuplicatedDemandElement(vehicleTag, id)) {
1928  writeError(TLF("There is another % with the same ID='%'.", toString(vehicleTag), id));
1929  return true;
1930  }
1931  }
1932  return false;
1933 }
1934 
1935 
1936 bool
1937 GNERouteHandler::isViaAttributeValid(const std::vector<std::string>& via) {
1938  for (const auto& edgeID : via) {
1939  if (myNet->getAttributeCarriers()->retrieveEdge(edgeID, false) == nullptr) {
1940  writeError(TLF("Via edge '%' doesn't exist.", edgeID));
1941  return false;
1942  }
1943  }
1944  return true;
1945 }
1946 
1947 
1948 bool
1950  for (SumoXMLTag personTag : std::vector<SumoXMLTag>({SUMO_TAG_PERSON, SUMO_TAG_PERSONFLOW})) {
1951  if (!checkDuplicatedDemandElement(personTag, id)) {
1952  writeError(TLF("There is another % with the same ID='%'.", toString(personTag), id));
1953  return true;
1954  }
1955  }
1956  return false;
1957 }
1958 
1959 
1960 bool
1962  for (SumoXMLTag containerTag : std::vector<SumoXMLTag>({SUMO_TAG_CONTAINER, SUMO_TAG_CONTAINERFLOW})) {
1963  if (!checkDuplicatedDemandElement(containerTag, id)) {
1964  writeError(TLF("There is another % with the same ID='%'.", toString(containerTag), id));
1965  return true;
1966  }
1967  }
1968  return false;
1969 }
1970 
1971 
1972 void
1973 GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1974  // get pointer to net
1975  GNENet* net = originalVehicle->getNet();
1976  // check if transform after creation
1977  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1978  // declare route handler
1979  GNERouteHandler routeHandler("", net, true, false);
1980  // make a copy of the vehicle parameters
1981  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1982  // obtain vClass
1983  const auto vClass = originalVehicle->getVClass();
1984  // set "yellow" as original route color
1985  RGBColor routeColor = RGBColor::YELLOW;
1986  // declare edges
1987  std::vector<GNEEdge*> routeEdges;
1988  // obtain edges depending of tag
1989  if (originalVehicle->getTagProperty().vehicleRoute()) {
1990  // get route edges
1991  routeEdges = originalVehicle->getParentDemandElements().at(1)->getParentEdges();
1992  // get original route color
1993  routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1994  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1995  // get embedded route edges
1996  routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1997  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1998  // calculate path using from-via-to edges
1999  routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
2000  }
2001  // declare edge IDs
2002  std::vector<std::string> edgeIDs;
2003  for (const auto& edge : routeEdges) {
2004  edgeIDs.push_back(edge->getID());
2005  }
2006  // only continue if edges are valid
2007  if (routeEdges.empty()) {
2008  // declare header
2009  const std::string header = "Problem transforming to vehicle";
2010  // declare message
2011  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
2012  // write warning
2013  WRITE_DEBUG("Opened FXMessageBox " + header);
2014  // open message box
2015  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2016  // write warning if netedit is running in testing mode
2017  WRITE_DEBUG("Closed FXMessageBox " + header);
2018  } else {
2019  // begin undo-redo operation
2020  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
2021  // first delete vehicle
2022  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2023  // check if new vehicle must have an embedded route
2024  if (createEmbeddedRoute) {
2025  // change tag in vehicle parameters
2026  vehicleParameters.tag = GNE_TAG_VEHICLE_WITHROUTE;
2027  // create a flow with embebbed routes
2029  CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
2030  // fill parameters
2031  vehicleBaseOBject->setTag(SUMO_TAG_VEHICLE);
2032  vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
2033  vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
2034  // build embedded route
2035  routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
2036  // delete vehicle base object
2037  delete vehicleBaseOBject;
2038  } else {
2039  // change tag in vehicle parameters
2040  vehicleParameters.tag = SUMO_TAG_VEHICLE;
2041  // generate route ID
2042  const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
2043  // build route
2044  routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
2045  // set route ID in vehicle parameters
2046  vehicleParameters.routeid = routeID;
2047  // create vehicle
2048  routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
2049  }
2050  // end undo-redo operation
2051  net->getViewNet()->getUndoList()->end();
2052  // check if inspect
2053  if (inspectAfterTransform) {
2054  // get created element
2055  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2056  // inspect it
2057  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2058  }
2059  }
2060 }
2061 
2062 
2063 void
2064 GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
2065  // get pointer to net
2066  GNENet* net = originalVehicle->getNet();
2067  // check if transform after creation
2068  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2069  // declare route handler
2070  GNERouteHandler routeHandler("", net, true, false);
2071  // obtain vehicle parameters
2072  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2073  // obtain vClass
2074  const auto vClass = originalVehicle->getVClass();
2075  // set "yellow" as original route color
2076  RGBColor routeColor = RGBColor::YELLOW;
2077  // declare edges
2078  std::vector<GNEEdge*> routeEdges;
2079  // obtain edges depending of tag
2080  if (originalVehicle->getTagProperty().vehicleRoute()) {
2081  // get route edges
2082  routeEdges = originalVehicle->getParentDemandElements().back()->getParentEdges();
2083  // get original route color
2084  routeColor = originalVehicle->getParentDemandElements().back()->getColor();
2085  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
2086  // get embedded route edges
2087  routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
2088  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
2089  // calculate path using from-via-to edges
2090  routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
2091  }
2092  // declare edge IDs
2093  std::vector<std::string> edgeIDs;
2094  for (const auto& edge : routeEdges) {
2095  edgeIDs.push_back(edge->getID());
2096  }
2097  // only continue if edges are valid
2098  if (routeEdges.empty()) {
2099  // declare header
2100  const std::string header = "Problem transforming to vehicle";
2101  // declare message
2102  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
2103  // write warning
2104  WRITE_DEBUG("Opened FXMessageBox " + header);
2105  // open message box
2106  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2107  // write warning if netedit is running in testing mode
2108  WRITE_DEBUG("Closed FXMessageBox " + header);
2109  } else {
2110  // begin undo-redo operation
2111  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
2112  // first delete vehicle
2113  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2114  // change depart
2115  if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
2116  // get template flow
2118  // set flow parameters
2119  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2120  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2121  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2122  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2123  // by default, number and end enabled
2124  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2125  }
2126  // check if new vehicle must have an embedded route
2127  if (createEmbeddedRoute) {
2128  // change tag in vehicle parameters
2129  vehicleParameters.tag = GNE_TAG_FLOW_WITHROUTE;
2130  // create a flow with embebbed routes
2132  CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
2133  // fill parameters
2134  vehicleBaseOBject->setTag(SUMO_TAG_FLOW);
2135  vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
2136  vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
2137  // build embedded route
2138  routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
2139  // delete vehicle base object
2140  delete vehicleBaseOBject;
2141  } else {
2142  // change tag in vehicle parameters
2143  vehicleParameters.tag = GNE_TAG_FLOW_ROUTE;
2144  // generate a new route id
2145  const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
2146  // build route
2147  routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
2148  // set route ID in vehicle parameters
2149  vehicleParameters.routeid = routeID;
2150  // create vehicle
2151  routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
2152  }
2153  // end undo-redo operation
2154  net->getViewNet()->getUndoList()->end();
2155  // check if inspect
2156  if (inspectAfterTransform) {
2157  // get created element
2158  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2159  // inspect it
2160  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2161  }
2162  }
2163 }
2164 
2165 
2166 void
2168  // get pointer to net
2169  GNENet* net = originalVehicle->getNet();
2170  // check if transform after creation
2171  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2172  // declare route handler
2173  GNERouteHandler routeHandler("", net, true, false);
2174  // obtain vehicle parameters
2175  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2176  // get route
2177  GNEDemandElement* route = nullptr;
2178  // declare edges
2179  std::vector<GNEEdge*> edges;
2180  // obtain edges depending of tag
2181  if (originalVehicle->getTagProperty().vehicleRoute()) {
2182  // set route
2183  route = originalVehicle->getParentDemandElements().back();
2184  // get route edges
2185  edges = route->getParentEdges();
2186  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
2187  // get embedded route edges
2188  edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
2189  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
2190  // just take parent edges (from and to)
2191  edges = originalVehicle->getParentEdges();
2192  }
2193  // only continue if edges are valid
2194  if (edges.size() < 2) {
2195  // declare header
2196  const std::string header = "Problem transforming to vehicle";
2197  // declare message
2198  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
2199  // write warning
2200  WRITE_DEBUG("Opened FXMessageBox " + header);
2201  // open message box
2202  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2203  // write warning if netedit is running in testing mode
2204  WRITE_DEBUG("Closed FXMessageBox " + header);
2205  } else {
2206  // begin undo-redo operation
2207  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_TRIP));
2208  // first delete vehicle
2209  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2210  // check if route has to be deleted
2211  if (route && route->getChildDemandElements().empty()) {
2212  net->deleteDemandElement(route, net->getViewNet()->getUndoList());
2213  }
2214  // change tag in vehicle parameters
2215  vehicleParameters.tag = SUMO_TAG_TRIP;
2216  // create trip
2217  routeHandler.buildTrip(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
2218  // end undo-redo operation
2219  net->getViewNet()->getUndoList()->end();
2220  // check if inspect
2221  if (inspectAfterTransform) {
2222  // get created element
2223  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2224  // inspect it
2225  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2226  }
2227  }
2228 }
2229 
2230 
2231 void
2233  // get pointer to net
2234  GNENet* net = originalVehicle->getNet();
2235  // check if transform after creation
2236  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2237  // declare route handler
2238  GNERouteHandler routeHandler("", net, true, false);
2239  // obtain vehicle parameters
2240  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2241  // declare route
2242  GNEDemandElement* route = nullptr;
2243  // declare edges
2244  std::vector<GNEEdge*> edges;
2245  // obtain edges depending of tag
2246  if (originalVehicle->getTagProperty().vehicleRoute()) {
2247  // set route
2248  route = originalVehicle->getParentDemandElements().back();
2249  // get route edges
2250  edges = route->getParentEdges();
2251  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
2252  // get embedded route edges
2253  edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
2254  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
2255  // just take parent edges (from and to)
2256  edges = originalVehicle->getParentEdges();
2257  }
2258  // only continue if edges are valid
2259  if (edges.empty()) {
2260  // declare header
2261  const std::string header = "Problem transforming to vehicle";
2262  // declare message
2263  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
2264  // write warning
2265  WRITE_DEBUG("Opened FXMessageBox " + header);
2266  // open message box
2267  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2268  // write warning if netedit is running in testing mode
2269  WRITE_DEBUG("Closed FXMessageBox " + header);
2270  } else {
2271  // begin undo-redo operation
2272  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
2273  // first delete vehicle
2274  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2275  // check if route has to be deleted
2276  if (route && route->getChildDemandElements().empty()) {
2277  net->deleteDemandElement(route, net->getViewNet()->getUndoList());
2278  }
2279  // change depart
2280  if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
2281  // get template flow
2283  // set flow parameters
2284  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2285  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2286  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2287  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2288  // by default, number and end enabled
2289  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2290  }
2291  // change tag in vehicle parameters
2292  vehicleParameters.tag = SUMO_TAG_FLOW;
2293  // create flow
2294  routeHandler.buildFlow(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
2295  // end undo-redo operation
2296  net->getViewNet()->getUndoList()->end();
2297  // check if inspect
2298  if (inspectAfterTransform) {
2299  // get created element
2300  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2301  // inspect it
2302  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2303  }
2304  }
2305 }
2306 
2307 
2308 void
2310  // only continue if number of junctions are valid
2311  if (originalVehicle->getParentJunctions().empty()) {
2312  // declare header
2313  const std::string header = "Problem transforming to trip over junctions";
2314  // declare message
2315  const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
2316  // write warning
2317  WRITE_DEBUG("Opened FXMessageBox " + header);
2318  // open message box
2319  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2320  // write warning if netedit is running in testing mode
2321  WRITE_DEBUG("Closed FXMessageBox " + header);
2322  } else {
2323  // get pointer to net
2324  GNENet* net = originalVehicle->getNet();
2325  // check if transform after creation
2326  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2327  // declare route handler
2328  GNERouteHandler routeHandler("", net, true, false);
2329  // obtain vehicle parameters
2330  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2331  // begin undo-redo operation
2332  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_JUNCTIONS));
2333  // first delete vehicle
2334  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2335  // change tag in vehicle parameters
2336  vehicleParameters.tag = GNE_TAG_TRIP_JUNCTIONS;
2337  // create trip
2338  routeHandler.buildTripJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
2339  // end undo-redo operation
2340  net->getViewNet()->getUndoList()->end();
2341  // check if inspect
2342  if (inspectAfterTransform) {
2343  // get created element
2344  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2345  // inspect it
2346  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2347  }
2348  }
2349 }
2350 
2351 
2352 void
2354  // only continue if number of junctions are valid
2355  if (originalVehicle->getParentJunctions().empty()) {
2356  // declare header
2357  const std::string header = "Problem transforming to flow over junctions";
2358  // declare message
2359  const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
2360  // write warning
2361  WRITE_DEBUG("Opened FXMessageBox " + header);
2362  // open message box
2363  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2364  // write warning if netedit is running in testing mode
2365  WRITE_DEBUG("Closed FXMessageBox " + header);
2366  } else {
2367  // get pointer to net
2368  GNENet* net = originalVehicle->getNet();
2369  // check if transform after creation
2370  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2371  // declare route handler
2372  GNERouteHandler routeHandler("", net, true, false);
2373  // obtain vehicle parameters
2374  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2375  // begin undo-redo operation
2376  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_JUNCTIONS));
2377  // first delete vehicle
2378  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2379  // get template flow
2381  // set flow parameters
2382  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2383  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2384  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2385  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2386  // by default, number and end enabled
2387  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2388  // change tag in vehicle parameters
2389  vehicleParameters.tag = GNE_TAG_FLOW_JUNCTIONS;
2390  // create flow
2391  routeHandler.buildFlowJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
2392  // end undo-redo operation
2393  net->getViewNet()->getUndoList()->end();
2394  // check if inspect
2395  if (inspectAfterTransform) {
2396  // get created element
2397  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2398  // inspect it
2399  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2400  }
2401  }
2402 }
2403 
2404 
2405 void
2407  // only continue if number of junctions are valid
2408  if (originalVehicle->getParentAdditionals().empty()) {
2409  // declare header
2410  const std::string header = "Problem transforming to trip over TAZs";
2411  // declare message
2412  const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
2413  // write warning
2414  WRITE_DEBUG("Opened FXMessageBox " + header);
2415  // open message box
2416  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2417  // write warning if netedit is running in testing mode
2418  WRITE_DEBUG("Closed FXMessageBox " + header);
2419  } else {
2420  // get pointer to net
2421  GNENet* net = originalVehicle->getNet();
2422  // check if transform after creation
2423  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2424  // declare route handler
2425  GNERouteHandler routeHandler("", net, true, false);
2426  // obtain vehicle parameters
2427  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2428  // begin undo-redo operation
2429  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_TAZS));
2430  // first delete vehicle
2431  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2432  // change tag in vehicle parameters
2433  vehicleParameters.tag = GNE_TAG_TRIP_TAZS;
2434  // create trip
2435  routeHandler.buildTripTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
2436  // end undo-redo operation
2437  net->getViewNet()->getUndoList()->end();
2438  // check if inspect
2439  if (inspectAfterTransform) {
2440  // get created element
2441  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2442  // inspect it
2443  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2444  }
2445  }
2446 }
2447 
2448 
2449 void
2451  // only continue if number of junctions are valid
2452  if (originalVehicle->getParentAdditionals().empty()) {
2453  // declare header
2454  const std::string header = "Problem transforming to flow over TAZs";
2455  // declare message
2456  const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
2457  // write warning
2458  WRITE_DEBUG("Opened FXMessageBox " + header);
2459  // open message box
2460  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2461  // write warning if netedit is running in testing mode
2462  WRITE_DEBUG("Closed FXMessageBox " + header);
2463  } else {
2464  // get pointer to net
2465  GNENet* net = originalVehicle->getNet();
2466  // check if transform after creation
2467  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2468  // declare route handler
2469  GNERouteHandler routeHandler("", net, true, false);
2470  // obtain vehicle parameters
2471  SUMOVehicleParameter vehicleParameters = *originalVehicle;
2472  // begin undo-redo operation
2473  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_TAZS));
2474  // first delete vehicle
2475  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2476  // get template flow
2478  // set flow parameters
2479  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2480  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2481  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2482  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2483  // by default, number and end enabled
2484  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2485  // change tag in vehicle parameters
2486  vehicleParameters.tag = GNE_TAG_FLOW_TAZS;
2487  // create flow
2488  routeHandler.buildFlowTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
2489  // end undo-redo operation
2490  net->getViewNet()->getUndoList()->end();
2491  // check if inspect
2492  if (inspectAfterTransform) {
2493  // get created element
2494  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2495  // inspect it
2496  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2497  }
2498  }
2499 }
2500 
2501 
2502 void
2504  // get pointer to net
2505  GNENet* net = originalPerson->getNet();
2506  // check if transform after creation
2507  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
2508  // declare route handler
2509  GNERouteHandler routeHandler("", net, true, false);
2510  // obtain person parameters
2511  SUMOVehicleParameter personParameters = *originalPerson;
2512  // get person plans
2513  const auto personPlans = originalPerson->getChildDemandElements();
2514  // save ID
2515  const auto ID = personParameters.id;
2516  // set dummy ID
2517  personParameters.id = "%dummyID%";
2518  // begin undo-redo operation
2519  net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSON));
2520  // create personFlow
2521  routeHandler.buildPerson(nullptr, personParameters);
2522  // move all person plans to new person
2523  for (const auto& personPlan : personPlans) {
2524  personPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2525  }
2526  // delete original person plan
2527  net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2528  // restore ID of new person plan
2529  auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, "%dummyID%");
2530  newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2531  // finish undoList
2532  net->getViewNet()->getUndoList()->end();
2533  // check if inspect
2534  if (inspectAfterTransform) {
2535  // get created element
2536  auto transformedPerson = net->getAttributeCarriers()->retrieveDemandElement(personParameters.tag, personParameters.id);
2537  // inspect it
2538  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedPerson);
2539  }
2540 }
2541 
2542 
2543 void
2545  // get pointer to net
2546  GNENet* net = originalPerson->getNet();
2547  // check if transform after creation
2548  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
2549  // declare route handler
2550  GNERouteHandler routeHandler("", net, true, false);
2551  // obtain person parameters
2552  SUMOVehicleParameter personParameters = *originalPerson;
2553  // get person plans
2554  const auto personPlans = originalPerson->getChildDemandElements();
2555  // save ID
2556  const auto ID = personParameters.id;
2557  // set dummy ID
2558  personParameters.id = "%dummyID%";
2559  // begin undo-redo operation
2560  net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSONFLOW));
2561  // create personFlow
2562  routeHandler.buildPersonFlow(nullptr, personParameters);
2563  // move all person plans to new person
2564  for (const auto& personPlan : personPlans) {
2565  personPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2566  }
2567  // delete original person plan
2568  net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2569  // restore ID of new person plan
2570  auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, "%dummyID%");
2571  newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2572  // enable attributes
2573  newPerson->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2574  newPerson->enableAttribute(SUMO_ATTR_PERSONSPERHOUR, net->getViewNet()->getUndoList());
2575  // finish undoList
2576  net->getViewNet()->getUndoList()->end();
2577  // check if inspect
2578  if (inspectAfterTransform) {
2579  // get created element
2580  auto transformedPerson = net->getAttributeCarriers()->retrieveDemandElement(personParameters.tag, personParameters.id);
2581  // inspect it
2582  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedPerson);
2583  }
2584 }
2585 
2586 
2587 void
2589  // get pointer to net
2590  GNENet* net = originalContainer->getNet();
2591  // check if transform after creation
2592  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2593  // declare route handler
2594  GNERouteHandler routeHandler("", net, true, false);
2595  // obtain container parameters
2596  SUMOVehicleParameter containerParameters = *originalContainer;
2597  // get container plans
2598  const auto containerPlans = originalContainer->getChildDemandElements();
2599  // save ID
2600  const auto ID = containerParameters.id;
2601  // set dummy ID
2602  containerParameters.id = "%dummyID%";
2603  // begin undo-redo operation
2604  net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINER));
2605  // create containerFlow
2606  routeHandler.buildContainer(nullptr, containerParameters);
2607  // move all container plans to new container
2608  for (const auto& containerPlan : containerPlans) {
2609  containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2610  }
2611  // delete original container plan
2612  net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2613  // restore ID of new container plan
2614  auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, "%dummyID%");
2615  newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2616  // finish undoList
2617  net->getViewNet()->getUndoList()->end();
2618  // check if inspect
2619  if (inspectAfterTransform) {
2620  // get created element
2621  auto transformedContainer = net->getAttributeCarriers()->retrieveDemandElement(containerParameters.tag, containerParameters.id);
2622  // inspect it
2623  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedContainer);
2624  }
2625 }
2626 
2627 
2628 void
2630  // get pointer to net
2631  GNENet* net = originalContainer->getNet();
2632  // check if transform after creation
2633  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2634  // declare route handler
2635  GNERouteHandler routeHandler("", net, true, false);
2636  // obtain container parameters
2637  SUMOVehicleParameter containerParameters = *originalContainer;
2638  // get container plans
2639  const auto containerPlans = originalContainer->getChildDemandElements();
2640  // save ID
2641  const auto ID = containerParameters.id;
2642  // set dummy ID
2643  containerParameters.id = "%dummyID%";
2644  // begin undo-redo operation
2645  net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINERFLOW));
2646  // create containerFlow
2647  routeHandler.buildContainerFlow(nullptr, containerParameters);
2648  // move all container plans to new container
2649  for (const auto& containerPlan : containerPlans) {
2650  containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2651  }
2652  // delete original container plan
2653  net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2654  // restore ID of new container plan
2655  auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, "%dummyID%");
2656  newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2657  // enable attributes
2658  newContainer->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2659  newContainer->enableAttribute(SUMO_ATTR_CONTAINERSPERHOUR, net->getViewNet()->getUndoList());
2660  // finish undoList
2661  net->getViewNet()->getUndoList()->end();
2662  // check if inspect
2663  if (inspectAfterTransform) {
2664  // get created element
2665  auto transformedContainer = net->getAttributeCarriers()->retrieveDemandElement(containerParameters.tag, containerParameters.id);
2666  // inspect it
2667  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedContainer);
2668  }
2669 }
2670 
2671 
2672 bool
2674  // continue depending of element
2675  if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2676  return canReverse(element->getNet(), SVC_PEDESTRIAN, element->getParentEdges());
2677  } else if (element->getTagProperty().vehicleRoute()) {
2678  return canReverse(element->getNet(), element->getVClass(), element->getParentDemandElements().at(1)->getParentEdges());
2679  } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2680  return canReverse(element->getNet(), element->getVClass(), element->getChildDemandElements().front()->getParentEdges());
2681  } else if (element->getTagProperty().vehicleEdges()) {
2682  return canReverse(element->getNet(), element->getVClass(), element->getParentEdges());
2683  } else if (element->getTagProperty().vehicleJunctions()) {
2684  return (element->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(element->getVClass(),
2685  element->getParentJunctions().back(), element->getParentJunctions().front()).size() > 0);
2686  } else if (element->getTagProperty().vehicleTAZs()) {
2687  return true;
2688  } else {
2689  return false;
2690  }
2691 }
2692 
2693 
2694 bool
2695 GNERouteHandler::canReverse(GNENet* net, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
2696  if (edges.empty()) {
2697  return false;
2698  } else {
2699  // obtain opposite edges
2700  std::vector<GNEEdge*> reverseEdges;
2701  for (const auto& edge : edges) {
2702  const auto oppositeEdges = edge->getOppositeEdges();
2703  // stop if there isn't opposite edges for the current edge
2704  if (oppositeEdges.empty()) {
2705  return false;
2706  } else {
2707  reverseEdges.push_back(oppositeEdges.front());
2708  }
2709  }
2710  // reverse edges
2711  std::reverse(reverseEdges.begin(), reverseEdges.end());
2712  // now check if exist a path
2713  return (net->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, edges).size() > 0);
2714  }
2715 }
2716 
2717 
2718 void
2720  // get undo list
2721  auto undoList = element->getNet()->getViewNet()->getUndoList();
2722  // continue depending of element
2723  if (element->getTagProperty().vehicleRoute()) {
2724  // reverse parent route
2725  reverse(element->getParentDemandElements().at(1));
2726  } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2727  // reverse embedded route
2728  reverse(element->getChildDemandElements().front());
2729  } else if (element->getTagProperty().vehicleJunctions()) {
2730  // get from to junctions
2731  const auto fromJunction = element->getAttribute(SUMO_ATTR_FROM_JUNCTION);
2732  const auto toJunction = element->getAttribute(SUMO_ATTR_TO_JUNCTION);
2733  // swap both attributes
2734  element->setAttribute(SUMO_ATTR_FROM_JUNCTION, toJunction, undoList);
2735  element->setAttribute(SUMO_ATTR_TO_JUNCTION, fromJunction, undoList);
2736  } else if (element->getTagProperty().vehicleTAZs()) {
2737  // get from to TAZs
2738  const auto fromTAZ = element->getAttribute(SUMO_ATTR_FROM_TAZ);
2739  const auto toTAZ = element->getAttribute(SUMO_ATTR_TO_TAZ);
2740  // swap both attributes
2741  element->setAttribute(SUMO_ATTR_FROM_TAZ, toTAZ, undoList);
2742  element->setAttribute(SUMO_ATTR_TO_TAZ, fromTAZ, undoList);
2743  } else {
2744  // extract and reverse opposite edges
2745  std::vector<GNEEdge*> oppositeEdges;
2746  for (const auto& edge : element->getParentEdges()) {
2747  oppositeEdges.push_back(edge->getOppositeEdges().front());
2748  }
2749  std::reverse(oppositeEdges.begin(), oppositeEdges.end());
2750  if (element->isRoute()) {
2751  element->setAttribute(SUMO_ATTR_EDGES, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2752  } else {
2753  // set from and to
2754  element->setAttribute(SUMO_ATTR_FROM, oppositeEdges.front()->getID(), undoList);
2755  element->setAttribute(SUMO_ATTR_TO, oppositeEdges.back()->getID(), undoList);
2756  // check if add via attribute
2757  oppositeEdges.erase(oppositeEdges.begin());
2758  oppositeEdges.pop_back();
2759  if (oppositeEdges.size() > 0) {
2760  element->setAttribute(SUMO_ATTR_VIA, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2761  }
2762  }
2763  }
2764 }
2765 
2766 
2767 void
2769  GNEDemandElement* elementCopy = nullptr;
2770  if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2771  // make a copy of the route and reverse
2772  elementCopy = GNERoute::copyRoute(dynamic_cast<GNERoute*>(element));
2773  } else if (element->getTagProperty().isVehicle()) {
2774  // make a copy of the vehicle
2775  elementCopy = GNEVehicle::copyVehicle(dynamic_cast<GNEVehicle*>(element));
2776  }
2777  // reverse copied element
2778  reverse(elementCopy);
2779 }
2780 
2781 // ===========================================================================
2782 // protected
2783 // ===========================================================================
2784 
2785 GNEJunction*
2786 GNERouteHandler::parseJunction(const SumoXMLTag tag, const std::string& junctionID) {
2787  GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(junctionID, false);
2788  // empty junctions aren't allowed. If junction is empty, write error, clear junctions and stop
2789  if (junction == nullptr) {
2790  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_JUNCTION)));
2791  }
2792  return junction;
2793 }
2794 
2795 
2797 GNERouteHandler::parseTAZ(const SumoXMLTag tag, const std::string& TAZID) {
2799  // empty TAZs aren't allowed. If TAZ is empty, write error, clear TAZs and stop
2800  if (TAZ == nullptr) {
2801  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_TAZ)));
2802  }
2803  return TAZ;
2804 }
2805 
2806 
2807 GNEEdge*
2808 GNERouteHandler::parseEdge(const SumoXMLTag tag, const std::string& edgeID) {
2809  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2810  // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2811  if (edge == nullptr) {
2812  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2813  }
2814  return edge;
2815 }
2816 
2817 
2818 std::vector<GNEEdge*>
2819 GNERouteHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
2820  std::vector<GNEEdge*> edges;
2821  for (const auto& edgeID : edgeIDs) {
2822  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2823  // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2824  if (edge == nullptr) {
2825  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2826  edges.clear();
2827  return edges;
2828  } else {
2829  edges.push_back(edge);
2830  }
2831  }
2832  return edges;
2833 }
2834 
2835 
2837 GNERouteHandler::getType(const std::string& id) const {
2839  if (type == nullptr) {
2841  } else {
2842  return type;
2843  }
2844 }
2845 
2846 
2849  // check that sumoBaseObject has parent
2850  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2851  return nullptr;
2852  }
2853  if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSON) &&
2854  (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSONFLOW)) {
2855  return nullptr;
2856  }
2857  // try it with person
2859  // if empty, try it with personFlow
2860  if (personParent == nullptr) {
2862  } else {
2863  return personParent;
2864  }
2865 }
2866 
2867 
2870  // check that sumoBaseObject has parent
2871  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2872  return nullptr;
2873  }
2874  if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINER) &&
2875  (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2876  return nullptr;
2877  }
2878  // try it with container
2880  // if empty, try it with containerFlow
2881  if (containerParent == nullptr) {
2883  } else {
2884  return containerParent;
2885  }
2886 }
2887 
2888 
2891  // get parent object
2892  const CommonXMLStructure::SumoBaseObject* parentObject = obj->getParentSumoBaseObject();
2893  // check if object has parent
2894  if (parentObject == nullptr) {
2895  return nullptr;
2896  }
2897  // check number of children
2898  if (parentObject->getSumoBaseObjectChildren().size() < 2) {
2899  return nullptr;
2900  }
2901  // search position of the given plan obj in the parent children
2902  const auto itObj = std::find(parentObject->getSumoBaseObjectChildren().begin(), parentObject->getSumoBaseObjectChildren().end(), obj);
2903  // if itObj is the first element, return null
2904  if (itObj == parentObject->getSumoBaseObjectChildren().begin()) {
2905  return nullptr;
2906  }
2907  // get pevious itObj
2908  return *(itObj - 1);
2909 }
2910 
2911 
2912 GNEEdge*
2914  const auto previousPlanObj = getPreviousPlanObj(obj);
2915  // check if previous plan object has to edge
2916  if (previousPlanObj == nullptr) {
2917  return nullptr;
2918  } else {
2919  // continue depending of attributes
2920  if (previousPlanObj->hasStringAttribute(SUMO_ATTR_TO)) {
2921  return myNet->getAttributeCarriers()->retrieveEdge(previousPlanObj->getStringAttribute(SUMO_ATTR_TO), false);
2922  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_EDGE)) {
2923  return myNet->getAttributeCarriers()->retrieveEdge(previousPlanObj->getStringAttribute(SUMO_ATTR_EDGE), false);
2924  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_BUS_STOP)) {
2925  // busStop
2926  const auto busStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_BUS_STOP), false);
2927  if (busStop) {
2928  return busStop->getParentLanes().front()->getParentEdge();
2929  }
2930  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_TRAIN_STOP)) {
2931  // trainStop
2932  const auto trainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_TRAIN_STOP), false);
2933  if (trainStop) {
2934  return trainStop->getParentLanes().front()->getParentEdge();
2935  }
2936  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_CONTAINER_STOP)) {
2937  // containerStop
2938  const auto containerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_CONTAINER_STOP), false);
2939  if (containerStop) {
2940  return containerStop->getParentLanes().front()->getParentEdge();
2941  }
2942  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_EDGES)) {
2943  const auto edges = StringTokenizer(previousPlanObj->getStringAttribute(SUMO_ATTR_EDGE)).getVector();
2944  if (edges.size() > 0) {
2945  return myNet->getAttributeCarriers()->retrieveEdge(edges.back(), false);
2946  }
2947  } else if (previousPlanObj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
2948  auto route = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_ROUTE, previousPlanObj->getStringAttribute(SUMO_ATTR_ROUTE), false);
2949  if (route) {
2950  return route->getParentEdges().back();
2951  }
2952  }
2953  // no previous edge
2954  return nullptr;
2955  }
2956 }
2957 
2958 
2961  const auto previousPlanObj = getPreviousPlanObj(obj);
2962  // check if previous plan object has to TAZ
2963  if (previousPlanObj && previousPlanObj->hasStringAttribute(SUMO_ATTR_TO_TAZ)) {
2964  return myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, previousPlanObj->getStringAttribute(SUMO_ATTR_TO_TAZ), false);
2965  } else {
2966  return nullptr;
2967  }
2968 }
2969 
2970 
2971 GNEJunction*
2973  const auto previousPlanObj = getPreviousPlanObj(obj);
2974  // check if previous plan object has to junction
2975  if (previousPlanObj && previousPlanObj->hasStringAttribute(SUMO_ATTR_TO_JUNCTION)) {
2976  return myNet->getAttributeCarriers()->retrieveJunction(previousPlanObj->getStringAttribute(SUMO_ATTR_TO_JUNCTION), false);
2977  } else {
2978  return nullptr;
2979  }
2980 }
2981 
2982 
2985  const auto previousPlanObj = getPreviousPlanObj(obj);
2986  // check if previous plan object has to busStop
2987  if (previousPlanObj && previousPlanObj->hasStringAttribute(SUMO_ATTR_BUS_STOP)) {
2988  return myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_BUS_STOP), false);
2989  } else {
2990  return nullptr;
2991  }
2992 }
2993 
2994 
2997  const auto previousPlanObj = getPreviousPlanObj(obj);
2998  // check if previous plan object has to trainStop
2999  if (previousPlanObj && previousPlanObj->hasStringAttribute(SUMO_ATTR_TRAIN_STOP)) {
3000  return myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_TRAIN_STOP), false);
3001  } else {
3002  return nullptr;
3003  }
3004 }
3005 
3006 
3009  const auto previousPlanObj = getPreviousPlanObj(obj);
3010  // check if previous plan object has to containerStop
3011  if (previousPlanObj && previousPlanObj->hasStringAttribute(SUMO_ATTR_CONTAINER_STOP)) {
3012  return myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, previousPlanObj->getStringAttribute(SUMO_ATTR_CONTAINER_STOP), false);
3013  } else {
3014  return nullptr;
3015  }
3016 }
3017 
3018 
3019 bool
3021  const std::vector<std::string>& distributionElementIDs, const std::vector<double>& probabilities,
3022  std::vector<const GNEDemandElement*>& elements) {
3023  // get distribution tag and ID
3024  std::string distributionTag = toString(sumoBaseObject->getTag());
3025  std::string distributionID = sumoBaseObject->getStringAttribute(SUMO_ATTR_ID);
3026  // first parse vType IDs
3027  for (const auto& distributionElementID : distributionElementIDs) {
3028  auto distributionElement = myNet->getAttributeCarriers()->retrieveDemandElement(distributionElementTag, distributionElementID, false);
3029  if (distributionElement) {
3030  elements.push_back(distributionElement);
3031  } else {
3032  writeError(TLF("% with id '%' doesn't exist in % '%'", toString(distributionElementTag), distributionElementID, distributionTag, distributionID));
3033  return false;
3034 
3035  }
3036  }
3037  // check probabilities
3038  for (const auto& probability : probabilities) {
3039  if (probability < 0) {
3040  writeError(TLF("invalid probability % in % '%'", toString(probability), distributionTag, distributionID));
3041  return false;
3042  }
3043  }
3044  // check that number of elements and probabilities is the same
3045  if (elements.size() != probabilities.size()) {
3046  writeError(TLF("Invalid type distribution probabilities in % '%'. Must have the same number of elements", distributionTag, distributionID));
3047  return false;
3048  } else {
3049  return true;
3050  }
3051 }
3052 
3053 
3054 bool
3056  // retrieve demand element
3057  auto demandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false);
3058  // if demand exist, check if overwrite (delete)
3059  if (demandElement) {
3060  if (!myAllowUndoRedo) {
3061  // only overwrite if allow undo-redo
3062  return false;
3063  } else if (myOverwrite) {
3064  // update demand to overwrite
3065  myDemandToOverwrite = demandElement;
3066  return true;
3067  } else {
3068  // duplicated demand
3069  return false;
3070  }
3071  } else {
3072  // demand with these id doesn't exist, then all ok
3073  return true;
3074  }
3075 }
3076 
3077 
3078 void
3080  if (myDemandToOverwrite) {
3081  // remove element
3083  // reset pointer
3084  myDemandToOverwrite = nullptr;
3085  }
3086 }
3087 
3088 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:306
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#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 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 int VEHPARS_DEPARTLANE_SET
const int VEHPARS_DEPARTSPEED_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
waypoint placed over a parking area
@ 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
@ GNE_TAG_WALK_EDGES
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ GNE_TAG_STOP_BUSSTOP
stop placed over a busStop
@ SUMO_TAG_CONTAINERFLOW
@ GNE_TAG_WAYPOINT_TRAINSTOP
waypoint placed over a busStop
@ GNE_TAG_WAYPOINT_CONTAINERSTOP
waypoint placed over a containerStop
@ GNE_TAG_WAYPOINT_BUSSTOP
waypoint placed over a busStop
@ SUMO_TAG_BUS_STOP
A bus stop.
@ GNE_TAG_WAYPOINT_CHARGINGSTATION
waypoint placed over a charging station
@ GNE_TAG_STOPPERSON_BUSSTOP
@ 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_TRANSHIP_EDGES
@ 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.
@ 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_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
waypoint placed over a lane
@ SUMO_TAG_PERSON
@ GNE_TAG_STOP_LANE
stop placed over a lane
@ GNE_TAG_STOPPERSON_TRAINSTOP
@ GNE_TAG_STOP_TRAINSTOP
stop placed over a trainStop
@ GNE_TAG_STOP_CHARGINGSTATION
stop placed over a charging station
@ GNE_TAG_WALK_ROUTE
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_LINES
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VIA
@ SUMO_ATTR_CONTAINER_STOP
@ 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_CONTAINERSPERHOUR
@ SUMO_ATTR_MODES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_DEPARTPOS
@ 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_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
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
SumoXMLTag getTag() const
get XML myTag
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
void clear()
clear SumoBaseObject
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.
Definition: GNEAdditional.h:49
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 > getPersonStopTagIcon(const GNEEdge *edge, const GNEAdditional *busStop, const GNEAdditional *trainStop)
get the person stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getPersonTripTagIcon(const GNEEdge *fromEdge, const GNEEdge *toEdge, const GNEAdditional *fromTAZ, const GNEAdditional *toTAZ, const GNEJunction *fromJunction, const GNEJunction *toJunction, const GNEAdditional *fromBusStop, const GNEAdditional *toBusStop, const GNEAdditional *fromTrainStop, const GNEAdditional *toTrainStop)
get the personTrip tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getRideTagIcon(const GNEEdge *fromEdge, const GNEEdge *toEdge, const GNEAdditional *fromBusStop, const GNEAdditional *toBusStop, const GNEAdditional *fromTrainStop, const GNEAdditional *toTrainStop)
get the ride tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getContainerStopTagIcon(const GNEEdge *edge, const GNEAdditional *containerStop)
get the container stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTransportTagIcon(const GNEEdge *fromEdge, const GNEEdge *toEdge, const GNEAdditional *fromContainerStop, const GNEAdditional *toContainerStop)
get the transport tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTranshipTagIcon(const std::vector< GNEEdge * > &consecutiveEdges, const GNEEdge *fromEdge, const GNEEdge *toEdge, const GNEAdditional *fromContainerStop, const GNEAdditional *toContainerStop)
get the tranship tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getWalkTagIcon(const std::vector< GNEEdge * > &consecutiveEdges, const GNEDemandElement *route, const GNEEdge *fromEdge, const GNEEdge *toEdge, const GNEAdditional *fromTAZ, const GNEAdditional *toTAZ, const GNEJunction *fromJunction, const GNEJunction *toJunction, const GNEAdditional *fromBusStop, const GNEAdditional *toBusStop, const GNEAdditional *fromTrainStop, const GNEAdditional *toTrainStop)
get the walk 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 inspectSingleElement(GNEAttributeCarrier *AC)
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
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:672
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:122
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:134
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2055
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)
bool isRoute() const
check if pathElement is a route
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
static GNEPersonTrip * buildPersonTrip(GNENet *net, GNEDemandElement *personParent, GNEEdge *fromEdge, GNEAdditional *fromTAZ, GNEJunction *fromJunction, GNEAdditional *fromBusStop, GNEAdditional *fromTrainStop, GNEEdge *toEdge, GNEAdditional *toTAZ, GNEJunction *toJunction, GNEAdditional *toBusStop, GNEAdditional *toTrainStop, double arrivalPosition, const std::vector< std::string > &types, const std::vector< std::string > &modes, const std::vector< std::string > &lines)
general constructor for personTrip
GNEAdditional * getFromContainerStop() const
get from container stop
GNEJunction * getFromJunction() const
get from junction
double getClickedPositionOverLane() const
get clicked position over lane
const std::vector< std::string > getConsecutiveEdgeIDs() const
get consecutive edge IDs
GNEEdge * getToEdge() const
get to edge
GNEAdditional * getTrainStop() const
get trainStop
GNEAdditional * getFromTAZ() const
get from TAZ
GNEAdditional * getFromTrainStop() const
get from train stop
GNEAdditional * getToContainerStop() const
get to container stop
GNEAdditional * getFromBusStop() const
get from bus stop
GNEAdditional * getToTAZ() const
get to TAZ
GNEDemandElement * getRoute() const
get route
GNEEdge * getFromEdge() const
get from edge
GNEAdditional * getBusStop() const
get busStop
GNEAdditional * getContainerStop() const
get containerStop
GNEEdge * getEdge() const
get edge
GNEJunction * getToJunction() const
get to junction
GNEAdditional * getToTrainStop() const
get to train stop
GNEAdditional * getToBusStop() const
get to bus stop
void incRef(const std::string &debugMsg="")
Increase reference.
static GNERide * buildRide(GNENet *net, GNEDemandElement *personParent, GNEEdge *fromEdge, GNEAdditional *fromBusStop, GNEAdditional *fromTrainStop, GNEEdge *toEdge, GNEAdditional *toBusStop, GNEAdditional *toTrainStop, double arrivalPosition, const std::vector< std::string > &lines)
general constructor for rides
Definition: GNERide.cpp:35
Builds trigger objects for GNENet (busStops, chargingStations, detectors, etc..)
void buildTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeID)
build trip
bool isContainerIdDuplicated(const std::string &id)
check if there is already a container (Container or ContainerFlow) with the given ID
const bool myOverwrite
check if overwrite
bool isVehicleIdDuplicated(const std::string &id)
check if there is already a vehicle (Vehicle, Trip, Flow or Flow) with the given ID
void buildContainerFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &containerFlowParameters)
build container flow
static void addReverse(GNEDemandElement *element)
add reverse for given demand element
bool checkDuplicatedDemandElement(const SumoXMLTag tag, const std::string &id)
check if given ID correspond to a duplicated demand element
bool buildPersonPlan(const GNEDemandElement *planTemplate, GNEDemandElement *personParent, GNEAttributesCreator *personPlanAttributes, GNEPlanCreator *planCreator, const bool centerAfterCreation)
build person plan
CommonXMLStructure::SumoBaseObject * myPlanObject
pointer for person and container plans
GNEDemandElement * getPersonParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get person parent
GNEJunction * parseJunction(const SumoXMLTag tag, const std::string &junctionID)
parse junction
const bool myAllowUndoRedo
allow undo/redo
void overwriteDemandElement()
remove overwritten demand element
void buildPerson(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personParameters)
build person
void buildWalk(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &fromTAZID, const std::string &fromJunctionID, const std::string &fromBusStopID, const std::string &fromTrainStopID, const std::string &toEdgeID, const std::string &toTAZID, const std::string &toJunctionID, const std::string &toBusStopID, const std::string &toTrainStopID, const std::vector< std::string > &edgeIDs, const std::string &routeID, double arrivalPos)
build walk
static void transformToRouteFlow(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform routeFlow over an existent route
GNENet * myNet
pointer to GNENet
GNEAdditional * getPreviousPlanTAZ(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan TAZ
void buildFlowTAZs(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromTAZID, const std::string &toTAZID)
build flow over junctions
bool isPersonIdDuplicated(const std::string &id)
check if there is already a person (Person or PersonFlow) with the given ID
static void transformToContainerFlow(GNEContainer *originalContainer)
transform routeFlow over an existent route
void buildVehicleOverRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters)
build a vehicle over an existent route
static void transformToFlow(GNEVehicle *originalVehicle)
transform to flow
void buildTripTAZs(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromTAZID, const std::string &toTAZID)
build trip over TAZs
GNEEdge * parseEdge(const SumoXMLTag tag, const std::string &edgeID)
parse edge
void buildFlowOverRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters)
build a flow over an existent route
void buildTripJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build trip over junctions
void 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
void buildFlowJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build flow over junctions
GNEAdditional * getPreviousPlanTrainStop(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan trainStop
static bool canReverse(const GNEDemandElement *element)
reverse functions
bool isViaAttributeValid(const std::vector< std::string > &via)
check if via attribute is valid
void buildVType(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVTypeParameter &vTypeParameter)
build vType
GNEEdge * getPreviousPlanEdge(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan edge
GNEAdditional * getPreviousPlanContainerStop(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan containerStop
static void transformToTrip(GNEVehicle *originalVehicle)
transform to trip
void buildTransport(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &fromContainerStopID, const std::string &toEdgeID, const std::string &toContainerStopID, const std::vector< std::string > &lines, const double arrivalPos)
build transport
void buildRouteDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::vector< std::string > &routeIDs, const std::vector< double > &probabilities)
build route distribution
void buildPersonTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &fromTAZID, const std::string &fromJunctionID, const std::string &fromBusStopID, const std::string &fromTrainStopID, const std::string &toEdgeID, const std::string &toTAZID, const std::string &toJunctionID, const std::string &toBusStopID, const std::string &toTrainStopID, double arrivalPos, const std::vector< std::string > &types, const std::vector< std::string > &modes, const std::vector< std::string > &lines)
build person trip
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
void buildFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeIDs)
build flow
bool buildContainerPlan(const GNEDemandElement *planTemplate, GNEDemandElement *containerParent, GNEAttributesCreator *containerPlanAttributes, GNEPlanCreator *planCreator, const bool centerAfterCreation)
build container plan
GNEAdditional * parseTAZ(const SumoXMLTag tag, const std::string &TAZID)
parse TAZ
GNEDemandElement * getType(const std::string &id) const
get type (Either type o typeDistribution)
virtual ~GNERouteHandler()
Destructor.
void 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
void buildPersonFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personFlowParameters)
build person flow
const CommonXMLStructure::SumoBaseObject * getPreviousPlanObj(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan obj
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::vector< std::string > &edgeIDs)
parse edges
GNEJunction * getPreviousPlanJunction(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan junction
void buildTranship(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &fromContainerStopID, const std::string &toEdgeID, const std::string &toContainerStopID, const std::vector< std::string > &edgeIDs, const double speed, const double departPosition, const double arrivalPosition)
build tranship
GNEDemandElement * getContainerParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get container parent
GNEAdditional * getPreviousPlanBusStop(const CommonXMLStructure::SumoBaseObject *obj) const
get previous plan busStop
void buildStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter::Stop &stopParameters)
build stop
static void reverse(GNEDemandElement *element)
reverse given demand element
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
void buildPersonStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const std::string &busStopID, const std::string &trainStopID, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build person stop
void buildContainer(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &containerParameters)
build container
static void transformToPersonFlow(GNEPerson *originalPerson)
transform routeFlow over an existent 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
void 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
GNEDemandElement * myDemandToOverwrite
demand to overwrite (using undo-redo
static void transformToFlowTAZs(GNEVehicle *originalVehicle)
transform to flow over TAZs
GNERouteHandler(const std::string &file, GNENet *net, const bool allowUndoRedo, const bool overwrite)
Constructor.
void buildRide(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &fromBusStopID, const std::string &fromTrainStopID, const std::string &toEdgeID, const std::string &toBusStopID, const std::string &toTrainStopID, double arrivalPos, const std::vector< std::string > &lines)
build ride
static void transformToVehicle(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform vehicle functions
void buildContainerStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const std::string &containerStopID, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build container stop
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:729
static GNEStopPlan * buildContainerStopPlan(GNENet *net, GNEDemandElement *personParent, GNEEdge *edge, GNEAdditional *containerStop, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
general constructor for container stop plans
Definition: GNEStopPlan.cpp:60
static GNEStopPlan * buildPersonStopPlan(GNENet *net, GNEDemandElement *personParent, GNEEdge *edge, GNEAdditional *busStop, GNEAdditional *trainStop, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
general constructor for person stop plans
Definition: GNEStopPlan.cpp:37
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
bool isPersonTrip() const
return true if tag correspond to a person trip
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 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
static GNETranship * buildTranship(GNENet *net, GNEDemandElement *containerParent, GNEEdge *fromEdge, GNEAdditional *fromContainerStop, GNEEdge *toEdge, GNEAdditional *toContainerStop, std::vector< GNEEdge * > edgeList, const double departPosition, const double arrivalPosition, const double speed)
general constructor for tranships
Definition: GNETranship.cpp:36
static GNETransport * buildTransport(GNENet *net, GNEDemandElement *containerParent, GNEEdge *fromEdge, GNEAdditional *fromContainerStop, GNEEdge *toEdge, GNEAdditional *toContainerStop, double arrivalPosition)
general constructor for walks
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 void overwriteVType(GNEDemandElement *vType, const SUMOVTypeParameter newVTypeParameter, GNEUndoList *undoList)
overwrite all values of GNEVType with a SUMOVTypeParameter
Definition: GNEVType.cpp:964
GNETagSelector * getVehicleTagSelector() const
get vehicle tag selector (needed for transform vehicles)
SUMOVehicleClass getVClass() const
obtain VClass related with this demand element
Definition: GNEVehicle.cpp:723
static GNEDemandElement * copyVehicle(const GNEVehicle *originalVehicle)
create a copy of the given vehicle
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
GNEVehicleFrame * getVehicleFrame() const
get frame for DEMAND_VEHICLE
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
static GNEWalk * buildWalk(GNENet *net, GNEDemandElement *personParent, GNEEdge *fromEdge, GNEAdditional *fromTAZ, GNEJunction *fromJunction, GNEAdditional *fromBusStop, GNEAdditional *fromTrainStop, GNEEdge *toEdge, GNEAdditional *toTAZ, GNEJunction *toJunction, GNEAdditional *toBusStop, GNEAdditional *toTrainStop, std::vector< GNEEdge * > edgeList, GNEDemandElement *route, double arrivalPosition)
general constructor for walks
Definition: GNEWalk.cpp:37
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
Definition: Parameterised.h:45
static const RGBColor YELLOW
Definition: RGBColor.h:188
static const RGBColor INVISIBLE
Definition: RGBColor.h:195
void writeError(const std::string &error)
write error and enable error creating element
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 parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
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.
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)
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.
bool wasSet(int what) const
Returns whether the given parameter was set.
std::vector< std::string > getVector()
return vector of strings