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 double arrivalPos, const std::vector<std::string>& types, const std::vector<std::string>& modes,
612  const std::vector<std::string>& lines, const double walkFactor, const std::string& group) {
613  // get values
614  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
615  const auto tagIcon = GNEDemandElementPlan::getPersonTripTagIcon(planParameters);
616  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
617  // check conditions
618  if (personParent == nullptr) {
619  WRITE_WARNING(TL("invalid person parent"));
620  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
621  WRITE_WARNING(TL("invalid combination for personTrip"));
622  } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
623  // build person trip
624  GNEDemandElement* personTrip = new GNEPersonTrip(myNet, tagIcon.first, tagIcon.second, personParent, planParents,
625  arrivalPos, types, modes, lines, walkFactor, group);
626  // continue depending of undo.redo
627  if (myAllowUndoRedo) {
628  myNet->getViewNet()->getUndoList()->begin(personTrip, TLF("add % in '%'", personTrip->getTagStr(), personParent->getID()));
630  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
631  myNet->getViewNet()->getUndoList()->end();
632  } else {
634  // set child references
635  personParent->addChildElement(personTrip);
636  planParents.addChildElements(personTrip);
637  personTrip->incRef("buildPersonTrip");
638  }
639  }
640 }
641 
642 
643 void
645  const double arrivalPos, const double speed, const SUMOTime duration) {
646  // get values
647  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
648  const auto tagIcon = GNEDemandElementPlan::getWalkTagIcon(planParameters);
649  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
650  // check conditions
651  if (personParent == nullptr) {
652  WRITE_WARNING(TL("invalid person parent"));
653  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
654  WRITE_WARNING(TL("invalid combination for personTrip"));
655  } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
656  // build person trip
657  GNEDemandElement* walk = new GNEWalk(myNet, tagIcon.first, tagIcon.second, personParent, planParents, arrivalPos, speed, duration);
658  // continue depending of undo.redo
659  if (myAllowUndoRedo) {
660  myNet->getViewNet()->getUndoList()->begin(walk, TLF("add % in '%'", walk->getTagStr(), personParent->getID()));
662  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
663  myNet->getViewNet()->getUndoList()->end();
664  } else {
666  // set child references
667  personParent->addChildElement(walk);
668  planParents.addChildElements(walk);
669  walk->incRef("buildWalk");
670  }
671  }
672 }
673 
674 
675 void
677  const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
678  // get values
679  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
680  const auto tagIcon = GNEDemandElementPlan::getRideTagIcon(planParameters);
681  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
682  // check conditions
683  if (personParent == nullptr) {
684  WRITE_WARNING(TL("invalid person parent"));
685  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
686  WRITE_WARNING(TL("invalid combination for ride"));
687  } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
688  // build ride
689  GNEDemandElement* ride = new GNERide(myNet, tagIcon.first, tagIcon.second, personParent, planParents, arrivalPos, lines, group);
690  // continue depending of undo-redo
691  if (myAllowUndoRedo) {
692  myNet->getViewNet()->getUndoList()->begin(ride, TLF("add % in '%'", ride->getTagStr(), personParent->getID()));
694  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
695  myNet->getViewNet()->getUndoList()->end();
696  } else {
698  // set child references
699  personParent->addChildElement(ride);
700  planParents.addChildElements(ride);
701  ride->incRef("buildRide");
702  }
703  }
704 }
705 
706 
707 void
708 GNERouteHandler::buildContainer(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerParameters) {
709  // first check if ID is duplicated
710  if (!isContainerIdDuplicated(containerParameters.id)) {
711  // obtain type
712  GNEDemandElement* type = getType(containerParameters.vtypeid);
713  if (type == nullptr) {
714  writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerParameters.vtypeid, toString(containerParameters.tag), containerParameters.id));
715  } else {
716  // create container using containerParameters
717  GNEDemandElement* container = new GNEContainer(SUMO_TAG_CONTAINER, myNet, type, containerParameters);
718  if (myAllowUndoRedo) {
719  myNet->getViewNet()->getUndoList()->begin(container, TL("add ") + container->getTagStr() + " '" + container->getID() + "'");
721  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(container, true), true);
722  myNet->getViewNet()->getUndoList()->end();
723  } else {
725  // set container as child of type
726  type->addChildElement(container);
727  container->incRef("buildContainer");
728  }
729  }
730  }
731 }
732 
733 
734 void
735 GNERouteHandler::buildContainerFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerFlowParameters) {
736  // first check if ID is duplicated
737  if (!isContainerIdDuplicated(containerFlowParameters.id)) {
738  // obtain type
739  GNEDemandElement* type = getType(containerFlowParameters.vtypeid);
740  if (type == nullptr) {
741  writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerFlowParameters.vtypeid, toString(containerFlowParameters.tag), containerFlowParameters.id));
742  } else {
743  // create containerFlow using containerFlowParameters
744  GNEDemandElement* containerFlow = new GNEContainer(SUMO_TAG_CONTAINERFLOW, myNet, type, containerFlowParameters);
745  if (myAllowUndoRedo) {
746  myNet->getViewNet()->getUndoList()->begin(containerFlow, TL("add ") + containerFlow->getTagStr() + " '" + containerFlow->getID() + "'");
748  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(containerFlow, true), true);
749  myNet->getViewNet()->getUndoList()->end();
750  } else {
752  // set containerFlow as child of type
753  type->addChildElement(containerFlow);
754  containerFlow->incRef("buildContainerFlow");
755  }
756  }
757  }
758 }
759 
760 
761 void
763  const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
764  // get values
765  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
766  const auto tagIcon = GNEDemandElementPlan::getTransportTagIcon(planParameters);
767  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
768  // check conditions
769  if (containerParent == nullptr) {
770  WRITE_WARNING(TL("invalid container parent"));
771  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
772  WRITE_WARNING(TL("invalid combination for personTrip"));
773  } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
774  // build transport
775  GNEDemandElement* transport = new GNETransport(myNet, tagIcon.first, tagIcon.second, containerParent, planParents, arrivalPos, lines, group);
776  // continue depending of undo-redo
777  if (myAllowUndoRedo) {
778  myNet->getViewNet()->getUndoList()->begin(transport, TLF("add % in '%'", transport->getTagStr(), containerParent->getID()));
780  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
781  myNet->getViewNet()->getUndoList()->end();
782  } else {
784  // set child references
785  containerParent->addChildElement(transport);
786  planParents.addChildElements(transport);
787  transport->incRef("buildTransport");
788  }
789  }
790 }
791 
792 
793 void
795  const double arrivalPosition, const double departPosition, const double speed, const SUMOTime duration) {
796  // get values
797  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
798  const auto tagIcon = GNEDemandElementPlan::getTranshipTagIcon(planParameters);
799  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
800  // check conditions
801  if (containerParent == nullptr) {
802  WRITE_WARNING(TL("invalid container parent"));
803  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
804  WRITE_WARNING(TL("invalid combination for personTrip"));
805  } else if (duration < 0) {
806  WRITE_WARNING(TL("tranship's duration cannot be negative"));
807  } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
808  // build tranship
809  GNEDemandElement* tranship = new GNETranship(myNet, tagIcon.first, tagIcon.second, containerParent, planParents,
810  arrivalPosition, departPosition, speed, duration);
811  // continue depending of undo-redo
812  if (myAllowUndoRedo) {
813  myNet->getViewNet()->getUndoList()->begin(tranship, TLF("add % in '%'", tranship->getTagStr(), containerParent->getID()));
815  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
816  myNet->getViewNet()->getUndoList()->end();
817  } else {
819  // set child references
820  containerParent->addChildElement(tranship);
821  planParents.addChildElements(tranship);
822  tranship->incRef("buildTranship");
823  }
824  }
825 }
826 
827 
828 void
830  const double endPos, const SUMOTime duration, const SUMOTime until,
831  const std::string& actType, const bool friendlyPos, const int parameterSet) {
832  // get values
833  GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
834  const auto tagIcon = GNEDemandElementPlan::getPersonStopTagIcon(planParameters);
835  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
836  // check conditions
837  if (personParent == nullptr) {
838  WRITE_WARNING(TL("invalid person parent"));
839  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
840  WRITE_WARNING(TL("invalid combination for person stop"));
841  } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
842  // build person stop
843  GNEDemandElement* stopPlan = new GNEStopPlan(myNet, tagIcon.first, tagIcon.second, personParent, planParents,
844  endPos, duration, until, actType, friendlyPos, parameterSet);
845  // continue depending of undo-redo
846  if (myAllowUndoRedo) {
847  myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), personParent->getID()));
849  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
850  myNet->getViewNet()->getUndoList()->end();
851  } else {
853  // set child references
854  personParent->addChildElement(stopPlan);
855  planParents.addChildElements(stopPlan);
856  stopPlan->incRef("buildPersonStop");
857  }
858  }
859 }
860 
861 
862 void
864  const double endPos, const SUMOTime duration,
865  const SUMOTime until, const std::string& actType, const bool friendlyPos, const int parameterSet) {
866  // get values
867  GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
868  const auto tagIcon = GNEDemandElementPlan::getContainerStopTagIcon(planParameters);
869  GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
870  // check conditions
871  if (containerParent == nullptr) {
872  WRITE_WARNING(TL("invalid container parent"));
873  } else if (tagIcon.first == SUMO_TAG_NOTHING) {
874  WRITE_WARNING(TL("invalid combination for containerStop"));
875  } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
876  // build container stop
877  GNEDemandElement* stopPlan = new GNEStopPlan(myNet, tagIcon.first, tagIcon.second, containerParent, planParents,
878  endPos, duration, until, actType, friendlyPos, parameterSet);
879  // continue depending of undo-redo
880  if (myAllowUndoRedo) {
881  myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), containerParent->getID()));
883  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
884  myNet->getViewNet()->getUndoList()->end();
885  } else {
887  // set child references
888  containerParent->addChildElement(stopPlan);
889  planParents.addChildElements(stopPlan);
890  stopPlan->incRef("buildContainerStop");
891  }
892  }
893 }
894 
895 
896 void
898  const SUMOVehicleParameter::Stop& stopParameters) {
899  // get obj parent
900  const auto objParent = sumoBaseObject->getParentSumoBaseObject();
901  // continue depending of objParent
902  if (objParent == nullptr) {
903  WRITE_WARNING(TL("Stops needs a parent"));
904  } else if ((objParent->getTag() == SUMO_TAG_PERSON) || (objParent->getTag() == SUMO_TAG_PERSONFLOW)) {
905  buildPersonStop(sumoBaseObject, planParameters, stopParameters.endPos,
906  stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
907  } else if ((objParent->getTag() == SUMO_TAG_CONTAINER) || (objParent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
908  buildContainerStop(sumoBaseObject, planParameters, stopParameters.endPos,
909  stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
910  } else {
911  // get vehicle tag
912  SumoXMLTag vehicleTag = objParent->getTag();
913  if (vehicleTag == SUMO_TAG_VEHICLE) {
914  // check if vehicle is placed over route or with embedded route
915  if (!objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
916  vehicleTag = GNE_TAG_VEHICLE_WITHROUTE;
917  }
918  } else if (vehicleTag == SUMO_TAG_FLOW) {
919  if (objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
920  vehicleTag = GNE_TAG_FLOW_ROUTE;
921  } else if (objParent->hasStringAttribute(SUMO_ATTR_FROM) && objParent->hasStringAttribute(SUMO_ATTR_TO)) {
922  vehicleTag = SUMO_TAG_FLOW;
923  } else {
924  vehicleTag = GNE_TAG_FLOW_WITHROUTE;
925  }
926  }
927  // get stop parent
928  GNEDemandElement* stopParent = myNet->getAttributeCarriers()->retrieveDemandElement(vehicleTag, objParent->getStringAttribute(SUMO_ATTR_ID), false);
929  // check if stopParent exist
930  if (stopParent) {
931  // flag for waypoint (is like a stop, but with extra attribute speed)
932  bool waypoint = false;
933  // avoid waypoints for person and containers
934  if (!stopParent->getTagProperty().isPerson() && !stopParent->getTagProperty().isContainer()) {
935  waypoint = (sumoBaseObject->getStopParameter().parametersSet & STOP_SPEED_SET) || (sumoBaseObject->getStopParameter().speed > 0);
936  }
937  // declare pointers to parent elements
938  GNEAdditional* stoppingPlace = nullptr;
939  GNELane* lane = nullptr;
940  GNEEdge* edge = nullptr;
941  // declare stopTagType
942  SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
943  bool validParentDemandElement = true;
944  // check conditions
945  if (stopParameters.busstop.size() > 0) {
946  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
947  stopTagType = waypoint ? GNE_TAG_WAYPOINT_BUSSTOP : GNE_TAG_STOP_BUSSTOP;
948  // check if is a train stop
949  if (stoppingPlace == nullptr) {
950  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, stopParameters.busstop, false);
951  stopTagType = waypoint ? GNE_TAG_WAYPOINT_TRAINSTOP : GNE_TAG_STOP_TRAINSTOP;
952  }
953  // containers cannot stops in busStops
954  if (stopParent->getTagProperty().isContainer()) {
955  writeError(TL("Containers don't support stops at busStops or trainStops"));
956  validParentDemandElement = false;
957  }
958  } else if (stopParameters.containerstop.size() > 0) {
959  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
961  // persons cannot stops in containerStops
962  if (stopParent->getTagProperty().isPerson()) {
963  writeError(TL("Persons don't support stops at containerStops"));
964  validParentDemandElement = false;
965  }
966  } else if (stopParameters.chargingStation.size() > 0) {
967  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, stopParameters.chargingStation, false);
969  // check person and containers
970  if (stopParent->getTagProperty().isPerson()) {
971  writeError(TL("Persons don't support stops at chargingStations"));
972  validParentDemandElement = false;
973  } else if (stopParent->getTagProperty().isContainer()) {
974  writeError(TL("Containers don't support stops at chargingStations"));
975  validParentDemandElement = false;
976  }
977  } else if (stopParameters.parkingarea.size() > 0) {
978  stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
979  stopTagType = waypoint ? GNE_TAG_WAYPOINT_PARKINGAREA : GNE_TAG_STOP_PARKINGAREA;
980  // check person and containers
981  if (stopParent->getTagProperty().isPerson()) {
982  writeError(TL("Persons don't support stops at parkingAreas"));
983  validParentDemandElement = false;
984  } else if (stopParent->getTagProperty().isContainer()) {
985  writeError(TL("Containers don't support stops at parkingAreas"));
986  validParentDemandElement = false;
987  }
988  } else if (stopParameters.lane.size() > 0) {
989  lane = myNet->getAttributeCarriers()->retrieveLane(stopParameters.lane, false);
990  stopTagType = waypoint ? GNE_TAG_WAYPOINT_LANE : GNE_TAG_STOP_LANE;
991  } else if (stopParameters.edge.size() > 0) {
992  edge = myNet->getAttributeCarriers()->retrieveEdge(stopParameters.edge, false);
993  // check vehicles
994  if (stopParent->getTagProperty().isVehicle()) {
995  writeError(TL("vehicles don't support stops at edges"));
996  validParentDemandElement = false;
997  }
998  }
999  // overwrite lane with edge parent if we're handling a personStop
1000  if (lane && (stopParent->getTagProperty().isPerson() || stopParent->getTagProperty().isContainer())) {
1001  edge = lane->getParentEdge();
1002  lane = nullptr;
1003  }
1004  // first check that parent is valid
1005  if (validParentDemandElement) {
1006  // check if values are correct
1007  if (stoppingPlace && lane && edge) {
1008  writeError(TL("A stop must be defined either over a stoppingPlace, a edge or a lane"));
1009  } else if (!stoppingPlace && !lane && !edge) {
1010  writeError(TL("A stop requires only a stoppingPlace, edge or lane"));
1011  } else if (stoppingPlace) {
1012  // create stop using stopParameters and stoppingPlace
1013  GNEDemandElement* stop = nullptr;
1014  if (stopParent->getTagProperty().isPerson()) {
1015  if (stoppingPlace->getTagProperty().getTag() == SUMO_TAG_BUS_STOP) {
1016  stop = new GNEStop(GNE_TAG_STOPPERSON_BUSSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1017  } else {
1018  stop = new GNEStop(GNE_TAG_STOPPERSON_TRAINSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1019  }
1020  } else if (stopParent->getTagProperty().isContainer()) {
1021  stop = new GNEStop(GNE_TAG_STOPCONTAINER_CONTAINERSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1022  } else {
1023  stop = new GNEStop(stopTagType, myNet, stopParent, stoppingPlace, stopParameters);
1024  }
1025  // add it depending of undoDemandElements
1026  if (myAllowUndoRedo) {
1027  myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1029  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1030  myNet->getViewNet()->getUndoList()->end();
1031  } else {
1033  stoppingPlace->addChildElement(stop);
1034  stopParent->addChildElement(stop);
1035  stop->incRef("buildStoppingPlaceStop");
1036  }
1037  } else if (lane) {
1038  // create stop using stopParameters and lane (only for vehicles)
1039  GNEDemandElement* stop = new GNEStop(stopTagType, myNet, stopParent, lane, stopParameters);
1040  // add it depending of undoDemandElements
1041  if (myAllowUndoRedo) {
1042  myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1044  myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1045  myNet->getViewNet()->getUndoList()->end();
1046  } else {
1048  lane->addChildElement(stop);
1049  stopParent->addChildElement(stop);
1050  stop->incRef("buildLaneStop");
1051  }
1052  }
1053  }
1054  }
1055  }
1056 }
1057 
1058 
1059 bool
1061  GNEAttributesCreator* personPlanAttributes, GNEPlanCreator* planCreator,
1062  const bool centerAfterCreation) {
1063  // first check if person is valid
1064  if (personParent == nullptr) {
1065  return false;
1066  }
1067  // clear and set person object
1068  myPlanObject->clear();
1069  myPlanObject->setTag(personParent->getTagProperty().getTag());
1071  // declare personPlan object
1073  // get person plan attributes
1074  personPlanAttributes->getAttributesAndValues(personPlanObject, true);
1075  // get attributes
1076  const std::vector<std::string> types = personPlanObject->hasStringListAttribute(SUMO_ATTR_VTYPES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_VTYPES) :
1077  personPlanObject->hasStringAttribute(SUMO_ATTR_VTYPES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_VTYPES)) :
1078  std::vector<std::string>();
1079  const std::vector<std::string> modes = personPlanObject->hasStringListAttribute(SUMO_ATTR_MODES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_MODES) :
1080  personPlanObject->hasStringAttribute(SUMO_ATTR_MODES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_MODES)) :
1081  std::vector<std::string>();
1082  const std::vector<std::string> lines = personPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1083  personPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1084  std::vector<std::string>();
1085  const double arrivalPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1086  personPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1087  -1;
1088  const double endPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1089  personPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1090  planCreator->getClickedPositionOverLane();
1091  const SUMOTime duration = personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? personPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1092  personPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1093  0;
1094  const SUMOTime until = personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? personPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1095  personPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1096  0;
1097  const std::string actType = personPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? personPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1098  const bool friendlyPos = personPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? personPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1099  personPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(personPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1100  false;
1101  const double walkFactor = personPlanObject->hasDoubleAttribute(SUMO_ATTR_WALKFACTOR) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_WALKFACTOR) : 0;
1102  const std::string group = personPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? personPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1103  const double speed = personPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) : 0;
1104  // build depending of plan type
1105  if (planTemplate->getTagProperty().isPlanWalk()) {
1106  buildWalk(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, speed, duration);
1107  } else if (planTemplate->getTagProperty().isPlanPersonTrip()) {
1108  buildPersonTrip(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, types, modes, lines, walkFactor, group);
1109  } else if (planTemplate->getTagProperty().isPlanRide()) {
1110  buildRide(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1111  } else if (planTemplate->getTagProperty().isPlanStopPerson()) {
1112  // set specific stop parameters
1113  int parameterSet = 0;
1114  if (personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1115  parameterSet |= STOP_DURATION_SET;
1116  }
1117  if (personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1118  parameterSet |= STOP_UNTIL_SET;
1119  }
1120  buildPersonStop(personPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1121  }
1122  // get person
1123  const auto person = myNet->getAttributeCarriers()->retrieveDemandElement(personPlanObject->getParentSumoBaseObject()->getTag(),
1124  personPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1125  if (person) {
1126  // center view after creation
1127  if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(person->getPositionInView())) {
1128  myNet->getViewNet()->centerTo(person->getPositionInView(), false);
1129  }
1130  }
1131  delete personPlanObject;
1132  return true;
1133 }
1134 
1135 
1136 bool
1138  GNEAttributesCreator* containerPlanAttributes, GNEPlanCreator* planCreator,
1139  const bool centerAfterCreation) {
1140  // first check if container is valid
1141  if (containerParent == nullptr) {
1142  return false;
1143  }
1144  // clear and set container object
1145  myPlanObject->clear();
1146  myPlanObject->setTag(containerParent->getTagProperty().getTag());
1147  myPlanObject->addStringAttribute(SUMO_ATTR_ID, containerParent->getID());
1148  // declare containerPlan object
1150  // get container plan attributes
1151  containerPlanAttributes->getAttributesAndValues(containerPlanObject, true);
1152  // get attributes
1153  const double speed = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) :
1154  containerPlanObject->hasStringAttribute(SUMO_ATTR_SPEED) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_SPEED)) :
1155  0;
1156  const std::vector<std::string> lines = containerPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? containerPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1157  containerPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(containerPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1158  std::vector<std::string>();
1159  const double departPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_DEPARTPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS) :
1160  containerPlanObject->hasStringAttribute(SUMO_ATTR_DEPARTPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_DEPARTPOS)) :
1161  -1;
1162  const double arrivalPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1163  containerPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1164  -1;
1165  const double endPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1166  containerPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1167  planCreator->getClickedPositionOverLane();
1168  const SUMOTime duration = containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1169  containerPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1170  0;
1171  const SUMOTime until = containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1172  containerPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1173  0;
1174  const std::string actType = containerPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? containerPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1175  const bool friendlyPos = containerPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? containerPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1176  containerPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(containerPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1177  false;
1178  const std::string group = containerPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? containerPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1179  // build depending of plan type
1180  if (planTemplate->getTagProperty().isPlanTranship()) {
1181  buildTranship(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, departPos, speed, duration);
1182  } else if (planTemplate->getTagProperty().isPlanTransport()) {
1183  buildTransport(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1184  } else if (planTemplate->getTagProperty().isPlanStopContainer()) {
1185  // set stops specific parameters
1186  int parameterSet = 0;
1187  if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1188  parameterSet |= STOP_DURATION_SET;
1189  }
1190  if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1191  parameterSet |= STOP_UNTIL_SET;
1192  }
1193  buildContainerStop(containerPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1194  }
1195  // get container
1196  const auto container = myNet->getAttributeCarriers()->retrieveDemandElement(containerPlanObject->getParentSumoBaseObject()->getTag(),
1197  containerPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1198  if (container) {
1199  // center view after creation
1200  if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(container->getPositionInView())) {
1201  myNet->getViewNet()->centerTo(container->getPositionInView(), false);
1202  }
1203  }
1204  delete containerPlanObject;
1205  return true;
1206 }
1207 
1208 
1209 void
1211  const auto& tagProperty = originalPlan->getTagProperty();
1212  // clear and set container object
1213  myPlanObject->clear();
1214  myPlanObject->setTag(newParent->getTagProperty().getTag());
1216  // declare personPlan object for adding all attributes
1218  planObject->setTag(tagProperty.getTag());
1219  // declare parameters
1220  CommonXMLStructure::PlanParameters planParameters;
1221  // from-to elements
1222  if (tagProperty.planFromEdge()) {
1223  planParameters.fromEdge = originalPlan->getAttribute(SUMO_ATTR_FROM);
1224  }
1225  if (tagProperty.planToEdge()) {
1226  planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_TO);
1227  }
1228  if (tagProperty.planFromJunction()) {
1229  planParameters.fromJunction = originalPlan->getAttribute(SUMO_ATTR_FROM_JUNCTION);
1230  }
1231  if (tagProperty.planToJunction()) {
1232  planParameters.toJunction = originalPlan->getAttribute(SUMO_ATTR_TO_JUNCTION);
1233  }
1234  if (tagProperty.planFromTAZ()) {
1235  planParameters.fromTAZ = originalPlan->getAttribute(SUMO_ATTR_FROM_TAZ);
1236  }
1237  if (tagProperty.planToTAZ()) {
1238  planParameters.toTAZ = originalPlan->getAttribute(SUMO_ATTR_TO_TAZ);
1239  }
1240  if (tagProperty.planFromBusStop()) {
1241  planParameters.fromBusStop = originalPlan->getAttribute(GNE_ATTR_FROM_BUSSTOP);
1242  }
1243  if (tagProperty.planToBusStop()) {
1244  planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1245  }
1246  if (tagProperty.planFromTrainStop()) {
1247  planParameters.fromTrainStop = originalPlan->getAttribute(GNE_ATTR_FROM_TRAINSTOP);
1248  }
1249  if (tagProperty.planToTrainStop()) {
1250  planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1251  }
1252  if (tagProperty.planFromContainerStop()) {
1253  planParameters.fromContainerStop = originalPlan->getAttribute(GNE_ATTR_FROM_CONTAINERSTOP);
1254  }
1255  if (tagProperty.planToContainerStop()) {
1256  planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1257  }
1258  // single elements
1259  if (tagProperty.planEdge()) {
1260  planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_EDGE);
1261  }
1262  if (tagProperty.planBusStop()) {
1263  planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1264  }
1265  if (tagProperty.planTrainStop()) {
1266  planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1267  }
1268  if (tagProperty.planContainerStop()) {
1269  planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1270  }
1271  // route
1272  if (tagProperty.planRoute()) {
1273  planParameters.toRoute = originalPlan->getAttribute(SUMO_ATTR_ROUTE);
1274  }
1275  // path
1276  if (tagProperty.planConsecutiveEdges()) {
1277  planParameters.consecutiveEdges = GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(SUMO_ATTR_EDGES));
1278  }
1279  // other elements
1280  planObject->addTimeAttribute(SUMO_ATTR_DURATION, 60);
1281  planObject->addTimeAttribute(SUMO_ATTR_UNTIL, 0);
1282  planObject->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, 0);
1283  planObject->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, -1);
1284  planObject->addDoubleAttribute(SUMO_ATTR_ENDPOS, 0);
1285  planObject->addDoubleAttribute(SUMO_ATTR_SPEED, 1.39);
1286  planObject->addBoolAttribute(SUMO_ATTR_FRIENDLY_POS, false);
1287  // add rest of attributes
1288  for (const auto& attrProperty : tagProperty) {
1289  if (!planObject->hasStringAttribute(attrProperty.getAttr())) {
1290  if (attrProperty.isFloat()) {
1291  if (!originalPlan->getAttribute(attrProperty.getAttr()).empty()) {
1292  planObject->addDoubleAttribute(attrProperty.getAttr(), originalPlan->getAttributeDouble(attrProperty.getAttr()));
1293  }
1294  } else if (attrProperty.isSUMOTime()) {
1295  if (!originalPlan->getAttribute(attrProperty.getAttr()).empty()) {
1296  planObject->addTimeAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<SUMOTime>(originalPlan->getAttribute(attrProperty.getAttr())));
1297  }
1298  } else if (attrProperty.isBool()) {
1299  planObject->addBoolAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<bool>(originalPlan->getAttribute(attrProperty.getAttr())));
1300  } else if (attrProperty.isList()) {
1301  planObject->addStringListAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(attrProperty.getAttr())));
1302  } else {
1303  planObject->addStringAttribute(attrProperty.getAttr(), originalPlan->getAttribute(attrProperty.getAttr()));
1304  }
1305  }
1306  }
1307  // create plan
1308  if (tagProperty.isPlanPersonTrip()) {
1309  buildPersonTrip(planObject, planParameters,
1315  planObject->getStringAttribute(SUMO_ATTR_GROUP));
1316  } else if (tagProperty.isPlanWalk()) {
1317  buildWalk(planObject, planParameters,
1319  planObject->getDoubleAttribute(SUMO_ATTR_SPEED),
1320  planObject->getTimeAttribute(SUMO_ATTR_DURATION));
1321  } else if (tagProperty.isPlanRide()) {
1322  buildRide(planObject, planParameters,
1325  planObject->getStringAttribute(SUMO_ATTR_GROUP));
1326  } else if (tagProperty.isPlanStopPerson()) {
1327  // set parameters
1328  int parameterSet = 0;
1329  if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1330  parameterSet |= STOP_DURATION_SET;
1331  }
1332  if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1333  parameterSet |= STOP_UNTIL_SET;
1334  }
1335  buildPersonStop(planObject, planParameters,
1336  planObject->getDoubleAttribute(SUMO_ATTR_ENDPOS),
1337  planObject->getTimeAttribute(SUMO_ATTR_DURATION),
1338  planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1341  parameterSet);
1342  } else if (tagProperty.isPlanTransport()) {
1343  buildTransport(planObject, planParameters,
1346  planObject->getStringAttribute(SUMO_ATTR_GROUP));
1347  } else if (tagProperty.isPlanTranship()) {
1348  buildTranship(planObject, planParameters,
1351  planObject->getDoubleAttribute(SUMO_ATTR_SPEED),
1352  planObject->getTimeAttribute(SUMO_ATTR_DURATION));
1353  } else if (tagProperty.isPlanStopContainer()) {
1354  // set parameters
1355  int parameterSet = 0;
1356  if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1357  parameterSet |= STOP_DURATION_SET;
1358  }
1359  if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1360  parameterSet |= STOP_UNTIL_SET;
1361  }
1362  buildContainerStop(planObject, planParameters,
1363  planObject->getDoubleAttribute(SUMO_ATTR_ENDPOS),
1364  planObject->getTimeAttribute(SUMO_ATTR_DURATION),
1365  planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1368  parameterSet);
1369  } else {
1370  throw ProcessError("Invalid plan for duplicating");
1371  }
1372 }
1373 
1374 
1375 bool
1377  // declare vehicle tags vector
1378  const std::vector<SumoXMLTag> vehicleTags = {SUMO_TAG_VEHICLE, GNE_TAG_VEHICLE_WITHROUTE, SUMO_TAG_TRIP, GNE_TAG_TRIP_TAZS,
1380  };
1381  for (const auto& vehicleTag : vehicleTags) {
1382  if (!checkDuplicatedDemandElement(vehicleTag, id)) {
1383  writeError(TLF("There is another % with the same ID='%'.", toString(vehicleTag), id));
1384  return true;
1385  }
1386  }
1387  return false;
1388 }
1389 
1390 
1391 bool
1392 GNERouteHandler::isViaAttributeValid(const std::vector<std::string>& via) {
1393  for (const auto& edgeID : via) {
1394  if (myNet->getAttributeCarriers()->retrieveEdge(edgeID, false) == nullptr) {
1395  writeError(TLF("Via edge '%' doesn't exist.", edgeID));
1396  return false;
1397  }
1398  }
1399  return true;
1400 }
1401 
1402 
1403 bool
1405  for (SumoXMLTag personTag : std::vector<SumoXMLTag>({SUMO_TAG_PERSON, SUMO_TAG_PERSONFLOW})) {
1406  if (!checkDuplicatedDemandElement(personTag, id)) {
1407  writeError(TLF("There is another % with the same ID='%'.", toString(personTag), id));
1408  return true;
1409  }
1410  }
1411  return false;
1412 }
1413 
1414 
1415 bool
1417  for (SumoXMLTag containerTag : std::vector<SumoXMLTag>({SUMO_TAG_CONTAINER, SUMO_TAG_CONTAINERFLOW})) {
1418  if (!checkDuplicatedDemandElement(containerTag, id)) {
1419  writeError(TLF("There is another % with the same ID='%'.", toString(containerTag), id));
1420  return true;
1421  }
1422  }
1423  return false;
1424 }
1425 
1426 
1427 void
1428 GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1429  // get pointer to net
1430  GNENet* net = originalVehicle->getNet();
1431  // check if transform after creation
1432  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1433  // declare route handler
1434  GNERouteHandler routeHandler("", net, true, false);
1435  // make a copy of the vehicle parameters
1436  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1437  // obtain vClass
1438  const auto vClass = originalVehicle->getVClass();
1439  // set "yellow" as original route color
1440  RGBColor routeColor = RGBColor::YELLOW;
1441  // declare edges
1442  std::vector<GNEEdge*> routeEdges;
1443  // obtain edges depending of tag
1444  if (originalVehicle->getTagProperty().vehicleRoute()) {
1445  // get route edges
1446  routeEdges = originalVehicle->getParentDemandElements().at(1)->getParentEdges();
1447  // get original route color
1448  routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1449  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1450  // get embedded route edges
1451  routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1452  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1453  // calculate path using from-via-to edges
1454  routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1455  }
1456  // declare edge IDs
1457  std::vector<std::string> edgeIDs;
1458  for (const auto& edge : routeEdges) {
1459  edgeIDs.push_back(edge->getID());
1460  }
1461  // only continue if edges are valid
1462  if (routeEdges.empty()) {
1463  // declare header
1464  const std::string header = "Problem transforming to vehicle";
1465  // declare message
1466  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1467  // write warning
1468  WRITE_DEBUG("Opened FXMessageBox " + header);
1469  // open message box
1470  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1471  // write warning if netedit is running in testing mode
1472  WRITE_DEBUG("Closed FXMessageBox " + header);
1473  } else {
1474  // begin undo-redo operation
1475  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1476  // first delete vehicle
1477  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1478  // check if new vehicle must have an embedded route
1479  if (createEmbeddedRoute) {
1480  // change tag in vehicle parameters
1481  vehicleParameters.tag = GNE_TAG_VEHICLE_WITHROUTE;
1482  // create a flow with embebbed routes
1484  CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1485  // fill parameters
1486  vehicleBaseOBject->setTag(SUMO_TAG_VEHICLE);
1487  vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1488  vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1489  // build embedded route
1490  routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1491  // delete vehicle base object
1492  delete vehicleBaseOBject;
1493  } else {
1494  // change tag in vehicle parameters
1495  vehicleParameters.tag = SUMO_TAG_VEHICLE;
1496  // generate route ID
1497  const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1498  // build route
1499  routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
1500  // set route ID in vehicle parameters
1501  vehicleParameters.routeid = routeID;
1502  // create vehicle
1503  routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
1504  }
1505  // end undo-redo operation
1506  net->getViewNet()->getUndoList()->end();
1507  // check if inspect
1508  if (inspectAfterTransform) {
1509  // get created element
1510  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1511  // inspect it
1512  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1513  }
1514  }
1515 }
1516 
1517 
1518 void
1519 GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1520  // get pointer to net
1521  GNENet* net = originalVehicle->getNet();
1522  // check if transform after creation
1523  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1524  // declare route handler
1525  GNERouteHandler routeHandler("", net, true, false);
1526  // obtain vehicle parameters
1527  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1528  // obtain vClass
1529  const auto vClass = originalVehicle->getVClass();
1530  // set "yellow" as original route color
1531  RGBColor routeColor = RGBColor::YELLOW;
1532  // declare edges
1533  std::vector<GNEEdge*> routeEdges;
1534  // obtain edges depending of tag
1535  if (originalVehicle->getTagProperty().vehicleRoute()) {
1536  // get route edges
1537  routeEdges = originalVehicle->getParentDemandElements().back()->getParentEdges();
1538  // get original route color
1539  routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1540  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1541  // get embedded route edges
1542  routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1543  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1544  // calculate path using from-via-to edges
1545  routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1546  }
1547  // declare edge IDs
1548  std::vector<std::string> edgeIDs;
1549  for (const auto& edge : routeEdges) {
1550  edgeIDs.push_back(edge->getID());
1551  }
1552  // only continue if edges are valid
1553  if (routeEdges.empty()) {
1554  // declare header
1555  const std::string header = "Problem transforming to vehicle";
1556  // declare message
1557  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1558  // write warning
1559  WRITE_DEBUG("Opened FXMessageBox " + header);
1560  // open message box
1561  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1562  // write warning if netedit is running in testing mode
1563  WRITE_DEBUG("Closed FXMessageBox " + header);
1564  } else {
1565  // begin undo-redo operation
1566  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1567  // first delete vehicle
1568  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1569  // change depart
1570  if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
1571  // get template flow
1573  // set flow parameters
1574  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1575  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1576  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1577  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1578  // by default, number and end enabled
1579  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1580  }
1581  // check if new vehicle must have an embedded route
1582  if (createEmbeddedRoute) {
1583  // change tag in vehicle parameters
1584  vehicleParameters.tag = GNE_TAG_FLOW_WITHROUTE;
1585  // create a flow with embebbed routes
1587  CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1588  // fill parameters
1589  vehicleBaseOBject->setTag(SUMO_TAG_FLOW);
1590  vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1591  vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1592  // build embedded route
1593  routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1594  // delete vehicle base object
1595  delete vehicleBaseOBject;
1596  } else {
1597  // change tag in vehicle parameters
1598  vehicleParameters.tag = GNE_TAG_FLOW_ROUTE;
1599  // generate a new route id
1600  const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1601  // build route
1602  routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
1603  // set route ID in vehicle parameters
1604  vehicleParameters.routeid = routeID;
1605  // create vehicle
1606  routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
1607  }
1608  // end undo-redo operation
1609  net->getViewNet()->getUndoList()->end();
1610  // check if inspect
1611  if (inspectAfterTransform) {
1612  // get created element
1613  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1614  // inspect it
1615  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1616  }
1617  }
1618 }
1619 
1620 
1621 void
1623  // get pointer to net
1624  GNENet* net = originalVehicle->getNet();
1625  // check if transform after creation
1626  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1627  // declare route handler
1628  GNERouteHandler routeHandler("", net, true, false);
1629  // obtain vehicle parameters
1630  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1631  // get route
1632  GNEDemandElement* route = nullptr;
1633  // declare edges
1634  std::vector<GNEEdge*> edges;
1635  // obtain edges depending of tag
1636  if (originalVehicle->getTagProperty().vehicleRoute()) {
1637  // set route
1638  route = originalVehicle->getParentDemandElements().back();
1639  // get route edges
1640  edges = route->getParentEdges();
1641  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1642  // get embedded route edges
1643  edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1644  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1645  // just take parent edges (from and to)
1646  edges = originalVehicle->getParentEdges();
1647  }
1648  // only continue if edges are valid
1649  if (edges.size() < 2) {
1650  // declare header
1651  const std::string header = "Problem transforming to vehicle";
1652  // declare message
1653  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1654  // write warning
1655  WRITE_DEBUG("Opened FXMessageBox " + header);
1656  // open message box
1657  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1658  // write warning if netedit is running in testing mode
1659  WRITE_DEBUG("Closed FXMessageBox " + header);
1660  } else {
1661  // begin undo-redo operation
1662  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_TRIP));
1663  // first delete vehicle
1664  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1665  // check if route has to be deleted
1666  if (route && route->getChildDemandElements().empty()) {
1667  net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1668  }
1669  // change tag in vehicle parameters
1670  vehicleParameters.tag = SUMO_TAG_TRIP;
1671  // create trip
1672  routeHandler.buildTrip(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1673  // end undo-redo operation
1674  net->getViewNet()->getUndoList()->end();
1675  // check if inspect
1676  if (inspectAfterTransform) {
1677  // get created element
1678  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1679  // inspect it
1680  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1681  }
1682  }
1683 }
1684 
1685 
1686 void
1688  // get pointer to net
1689  GNENet* net = originalVehicle->getNet();
1690  // check if transform after creation
1691  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1692  // declare route handler
1693  GNERouteHandler routeHandler("", net, true, false);
1694  // obtain vehicle parameters
1695  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1696  // declare route
1697  GNEDemandElement* route = nullptr;
1698  // declare edges
1699  std::vector<GNEEdge*> edges;
1700  // obtain edges depending of tag
1701  if (originalVehicle->getTagProperty().vehicleRoute()) {
1702  // set route
1703  route = originalVehicle->getParentDemandElements().back();
1704  // get route edges
1705  edges = route->getParentEdges();
1706  } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1707  // get embedded route edges
1708  edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1709  } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1710  // just take parent edges (from and to)
1711  edges = originalVehicle->getParentEdges();
1712  }
1713  // only continue if edges are valid
1714  if (edges.empty()) {
1715  // declare header
1716  const std::string header = "Problem transforming to vehicle";
1717  // declare message
1718  const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1719  // write warning
1720  WRITE_DEBUG("Opened FXMessageBox " + header);
1721  // open message box
1722  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1723  // write warning if netedit is running in testing mode
1724  WRITE_DEBUG("Closed FXMessageBox " + header);
1725  } else {
1726  // begin undo-redo operation
1727  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1728  // first delete vehicle
1729  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1730  // check if route has to be deleted
1731  if (route && route->getChildDemandElements().empty()) {
1732  net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1733  }
1734  // change depart
1735  if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
1736  // get template flow
1738  // set flow parameters
1739  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1740  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1741  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1742  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1743  // by default, number and end enabled
1744  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1745  }
1746  // change tag in vehicle parameters
1747  vehicleParameters.tag = SUMO_TAG_FLOW;
1748  // create flow
1749  routeHandler.buildFlow(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1750  // end undo-redo operation
1751  net->getViewNet()->getUndoList()->end();
1752  // check if inspect
1753  if (inspectAfterTransform) {
1754  // get created element
1755  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1756  // inspect it
1757  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1758  }
1759  }
1760 }
1761 
1762 
1763 void
1765  // only continue if number of junctions are valid
1766  if (originalVehicle->getParentJunctions().empty()) {
1767  // declare header
1768  const std::string header = "Problem transforming to trip over junctions";
1769  // declare message
1770  const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
1771  // write warning
1772  WRITE_DEBUG("Opened FXMessageBox " + header);
1773  // open message box
1774  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1775  // write warning if netedit is running in testing mode
1776  WRITE_DEBUG("Closed FXMessageBox " + header);
1777  } else {
1778  // get pointer to net
1779  GNENet* net = originalVehicle->getNet();
1780  // check if transform after creation
1781  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1782  // declare route handler
1783  GNERouteHandler routeHandler("", net, true, false);
1784  // obtain vehicle parameters
1785  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1786  // begin undo-redo operation
1787  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_JUNCTIONS));
1788  // first delete vehicle
1789  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1790  // change tag in vehicle parameters
1791  vehicleParameters.tag = GNE_TAG_TRIP_JUNCTIONS;
1792  // create trip
1793  routeHandler.buildTripJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
1794  // end undo-redo operation
1795  net->getViewNet()->getUndoList()->end();
1796  // check if inspect
1797  if (inspectAfterTransform) {
1798  // get created element
1799  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1800  // inspect it
1801  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1802  }
1803  }
1804 }
1805 
1806 
1807 void
1809  // only continue if number of junctions are valid
1810  if (originalVehicle->getParentJunctions().empty()) {
1811  // declare header
1812  const std::string header = "Problem transforming to flow over junctions";
1813  // declare message
1814  const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
1815  // write warning
1816  WRITE_DEBUG("Opened FXMessageBox " + header);
1817  // open message box
1818  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1819  // write warning if netedit is running in testing mode
1820  WRITE_DEBUG("Closed FXMessageBox " + header);
1821  } else {
1822  // get pointer to net
1823  GNENet* net = originalVehicle->getNet();
1824  // check if transform after creation
1825  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1826  // declare route handler
1827  GNERouteHandler routeHandler("", net, true, false);
1828  // obtain vehicle parameters
1829  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1830  // begin undo-redo operation
1831  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_JUNCTIONS));
1832  // first delete vehicle
1833  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1834  // get template flow
1836  // set flow parameters
1837  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1838  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1839  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1840  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1841  // by default, number and end enabled
1842  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1843  // change tag in vehicle parameters
1844  vehicleParameters.tag = GNE_TAG_FLOW_JUNCTIONS;
1845  // create flow
1846  routeHandler.buildFlowJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
1847  // end undo-redo operation
1848  net->getViewNet()->getUndoList()->end();
1849  // check if inspect
1850  if (inspectAfterTransform) {
1851  // get created element
1852  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1853  // inspect it
1854  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1855  }
1856  }
1857 }
1858 
1859 
1860 void
1862  // only continue if number of junctions are valid
1863  if (originalVehicle->getParentAdditionals().empty()) {
1864  // declare header
1865  const std::string header = "Problem transforming to trip over TAZs";
1866  // declare message
1867  const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
1868  // write warning
1869  WRITE_DEBUG("Opened FXMessageBox " + header);
1870  // open message box
1871  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1872  // write warning if netedit is running in testing mode
1873  WRITE_DEBUG("Closed FXMessageBox " + header);
1874  } else {
1875  // get pointer to net
1876  GNENet* net = originalVehicle->getNet();
1877  // check if transform after creation
1878  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1879  // declare route handler
1880  GNERouteHandler routeHandler("", net, true, false);
1881  // obtain vehicle parameters
1882  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1883  // begin undo-redo operation
1884  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_TAZS));
1885  // first delete vehicle
1886  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1887  // change tag in vehicle parameters
1888  vehicleParameters.tag = GNE_TAG_TRIP_TAZS;
1889  // create trip
1890  routeHandler.buildTripTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
1891  // end undo-redo operation
1892  net->getViewNet()->getUndoList()->end();
1893  // check if inspect
1894  if (inspectAfterTransform) {
1895  // get created element
1896  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1897  // inspect it
1898  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1899  }
1900  }
1901 }
1902 
1903 
1904 void
1906  // only continue if number of junctions are valid
1907  if (originalVehicle->getParentAdditionals().empty()) {
1908  // declare header
1909  const std::string header = "Problem transforming to flow over TAZs";
1910  // declare message
1911  const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
1912  // write warning
1913  WRITE_DEBUG("Opened FXMessageBox " + header);
1914  // open message box
1915  FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1916  // write warning if netedit is running in testing mode
1917  WRITE_DEBUG("Closed FXMessageBox " + header);
1918  } else {
1919  // get pointer to net
1920  GNENet* net = originalVehicle->getNet();
1921  // check if transform after creation
1922  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1923  // declare route handler
1924  GNERouteHandler routeHandler("", net, true, false);
1925  // obtain vehicle parameters
1926  SUMOVehicleParameter vehicleParameters = *originalVehicle;
1927  // begin undo-redo operation
1928  net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_TAZS));
1929  // first delete vehicle
1930  net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1931  // get template flow
1933  // set flow parameters
1934  vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1935  vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1936  vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1937  vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1938  // by default, number and end enabled
1939  vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1940  // change tag in vehicle parameters
1941  vehicleParameters.tag = GNE_TAG_FLOW_TAZS;
1942  // create flow
1943  routeHandler.buildFlowTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
1944  // end undo-redo operation
1945  net->getViewNet()->getUndoList()->end();
1946  // check if inspect
1947  if (inspectAfterTransform) {
1948  // get created element
1949  auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1950  // inspect it
1951  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1952  }
1953  }
1954 }
1955 
1956 
1957 void
1959  // get pointer to net
1960  GNENet* net = originalPerson->getNet();
1961  // check if transform after creation
1962  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
1963  // declare route handler
1964  GNERouteHandler routeHandler("", net, true, false);
1965  // obtain person parameters
1966  SUMOVehicleParameter personParameters = *originalPerson;
1967  // save ID
1968  const auto ID = personParameters.id;
1969  // set dummy ID
1970  personParameters.id = "%dummyID%";
1971  // begin undo-redo operation
1972  net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSON));
1973  // create personFlow and get it
1974  routeHandler.buildPerson(nullptr, personParameters);
1975  auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, "%dummyID%");
1976  // duplicate plans in new person
1977  for (const auto& personPlan : originalPerson->getChildDemandElements()) {
1978  routeHandler.duplicatePlan(personPlan, newPerson);
1979  }
1980  // delete original person plan
1981  net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
1982  // restore ID of new person plan
1983  newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
1984  // finish undoList
1985  net->getViewNet()->getUndoList()->end();
1986  // check if inspect
1987  if (inspectAfterTransform) {
1989  }
1990 }
1991 
1992 
1993 void
1995  // get pointer to net
1996  GNENet* net = originalPerson->getNet();
1997  // check if transform after creation
1998  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
1999  // declare route handler
2000  GNERouteHandler routeHandler("", net, true, false);
2001  // obtain person parameters
2002  SUMOVehicleParameter personParameters = *originalPerson;
2003  // get person plans
2004  const auto personPlans = originalPerson->getChildDemandElements();
2005  // save ID
2006  const auto ID = personParameters.id;
2007  // set dummy ID
2008  personParameters.id = "%dummyID%";
2009  // begin undo-redo operation
2010  net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSONFLOW));
2011  // create personFlow and get it
2012  routeHandler.buildPersonFlow(nullptr, personParameters);
2013  auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, "%dummyID%");
2014  // move all person plans to new person
2015  for (const auto& personPlan : personPlans) {
2016  routeHandler.duplicatePlan(personPlan, newPerson);
2017  }
2018  // delete original person plan
2019  net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2020  // restore ID of new person plan
2021  newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2022  // enable attributes
2023  newPerson->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2024  newPerson->enableAttribute(SUMO_ATTR_PERSONSPERHOUR, net->getViewNet()->getUndoList());
2025  // finish undoList
2026  net->getViewNet()->getUndoList()->end();
2027  // check if inspect
2028  if (inspectAfterTransform) {
2030  }
2031 }
2032 
2033 
2034 void
2036  // get pointer to net
2037  GNENet* net = originalContainer->getNet();
2038  // check if transform after creation
2039  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2040  // declare route handler
2041  GNERouteHandler routeHandler("", net, true, false);
2042  // obtain container parameters
2043  SUMOVehicleParameter containerParameters = *originalContainer;
2044  // get container plans
2045  const auto containerPlans = originalContainer->getChildDemandElements();
2046  // save ID
2047  const auto ID = containerParameters.id;
2048  // set dummy ID
2049  containerParameters.id = "%dummyID%";
2050  // begin undo-redo operation
2051  net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINER));
2052  // create containerFlow
2053  routeHandler.buildContainer(nullptr, containerParameters);
2054  // move all container plans to new container
2055  for (const auto& containerPlan : containerPlans) {
2056  containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2057  }
2058  // delete original container plan
2059  net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2060  // restore ID of new container plan
2061  auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, "%dummyID%");
2062  newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2063  // finish undoList
2064  net->getViewNet()->getUndoList()->end();
2065  // check if inspect
2066  if (inspectAfterTransform) {
2067  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(newContainer);
2068  }
2069 }
2070 
2071 
2072 void
2074  // get pointer to net
2075  GNENet* net = originalContainer->getNet();
2076  // check if transform after creation
2077  const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2078  // declare route handler
2079  GNERouteHandler routeHandler("", net, true, false);
2080  // obtain container parameters
2081  SUMOVehicleParameter containerParameters = *originalContainer;
2082  // get container plans
2083  const auto containerPlans = originalContainer->getChildDemandElements();
2084  // save ID
2085  const auto ID = containerParameters.id;
2086  // set dummy ID
2087  containerParameters.id = "%dummyID%";
2088  // begin undo-redo operation
2089  net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINERFLOW));
2090  // create containerFlow
2091  routeHandler.buildContainerFlow(nullptr, containerParameters);
2092  // move all container plans to new container
2093  for (const auto& containerPlan : containerPlans) {
2094  containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2095  }
2096  // delete original container plan
2097  net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2098  // restore ID of new container plan
2099  auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, "%dummyID%");
2100  newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2101  // enable attributes
2102  newContainer->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2103  newContainer->enableAttribute(SUMO_ATTR_CONTAINERSPERHOUR, net->getViewNet()->getUndoList());
2104  // finish undoList
2105  net->getViewNet()->getUndoList()->end();
2106  // check if inspect
2107  if (inspectAfterTransform) {
2108  net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(newContainer);
2109  }
2110 }
2111 
2112 
2113 bool
2115  // continue depending of element
2116  if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2117  return canReverse(element->getNet(), SVC_PEDESTRIAN, element->getParentEdges());
2118  } else if (element->getTagProperty().vehicleRoute()) {
2119  return canReverse(element->getNet(), element->getVClass(), element->getParentDemandElements().at(1)->getParentEdges());
2120  } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2121  return canReverse(element->getNet(), element->getVClass(), element->getChildDemandElements().front()->getParentEdges());
2122  } else if (element->getTagProperty().vehicleEdges()) {
2123  return canReverse(element->getNet(), element->getVClass(), element->getParentEdges());
2124  } else if (element->getTagProperty().vehicleJunctions()) {
2125  return (element->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(element->getVClass(),
2126  element->getParentJunctions().back(), element->getParentJunctions().front()).size() > 0);
2127  } else if (element->getTagProperty().vehicleTAZs()) {
2128  return true;
2129  } else {
2130  return false;
2131  }
2132 }
2133 
2134 
2135 bool
2136 GNERouteHandler::canReverse(GNENet* net, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
2137  if (edges.empty()) {
2138  return false;
2139  } else {
2140  // obtain opposite edges
2141  std::vector<GNEEdge*> reverseEdges;
2142  for (const auto& edge : edges) {
2143  const auto oppositeEdges = edge->getOppositeEdges();
2144  // stop if there isn't opposite edges for the current edge
2145  if (oppositeEdges.empty()) {
2146  return false;
2147  } else {
2148  reverseEdges.push_back(oppositeEdges.front());
2149  }
2150  }
2151  // reverse edges
2152  std::reverse(reverseEdges.begin(), reverseEdges.end());
2153  // now check if exist a path
2154  return (net->getPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, edges).size() > 0);
2155  }
2156 }
2157 
2158 
2159 void
2161  // get undo list
2162  auto undoList = element->getNet()->getViewNet()->getUndoList();
2163  // continue depending of element
2164  if (element->getTagProperty().vehicleRoute()) {
2165  // reverse parent route
2166  reverse(element->getParentDemandElements().at(1));
2167  } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2168  // reverse embedded route
2169  reverse(element->getChildDemandElements().front());
2170  } else if (element->getTagProperty().vehicleJunctions()) {
2171  // get from to junctions
2172  const auto fromJunction = element->getAttribute(SUMO_ATTR_FROM_JUNCTION);
2173  const auto toJunction = element->getAttribute(SUMO_ATTR_TO_JUNCTION);
2174  // swap both attributes
2175  element->setAttribute(SUMO_ATTR_FROM_JUNCTION, toJunction, undoList);
2176  element->setAttribute(SUMO_ATTR_TO_JUNCTION, fromJunction, undoList);
2177  } else if (element->getTagProperty().vehicleTAZs()) {
2178  // get from to TAZs
2179  const auto fromTAZ = element->getAttribute(SUMO_ATTR_FROM_TAZ);
2180  const auto toTAZ = element->getAttribute(SUMO_ATTR_TO_TAZ);
2181  // swap both attributes
2182  element->setAttribute(SUMO_ATTR_FROM_TAZ, toTAZ, undoList);
2183  element->setAttribute(SUMO_ATTR_TO_TAZ, fromTAZ, undoList);
2184  } else {
2185  // extract and reverse opposite edges
2186  std::vector<GNEEdge*> oppositeEdges;
2187  for (const auto& edge : element->getParentEdges()) {
2188  oppositeEdges.push_back(edge->getOppositeEdges().front());
2189  }
2190  std::reverse(oppositeEdges.begin(), oppositeEdges.end());
2191  if (element->isRoute()) {
2192  element->setAttribute(SUMO_ATTR_EDGES, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2193  } else {
2194  // set from and to
2195  element->setAttribute(SUMO_ATTR_FROM, oppositeEdges.front()->getID(), undoList);
2196  element->setAttribute(SUMO_ATTR_TO, oppositeEdges.back()->getID(), undoList);
2197  // check if add via attribute
2198  oppositeEdges.erase(oppositeEdges.begin());
2199  oppositeEdges.pop_back();
2200  if (oppositeEdges.size() > 0) {
2201  element->setAttribute(SUMO_ATTR_VIA, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2202  }
2203  }
2204  }
2205 }
2206 
2207 
2208 void
2210  GNEDemandElement* elementCopy = nullptr;
2211  if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2212  // make a copy of the route and reverse
2213  elementCopy = GNERoute::copyRoute(dynamic_cast<GNERoute*>(element));
2214  } else if (element->getTagProperty().isVehicle()) {
2215  // make a copy of the vehicle
2216  elementCopy = GNEVehicle::copyVehicle(dynamic_cast<GNEVehicle*>(element));
2217  }
2218  // reverse copied element
2219  reverse(elementCopy);
2220 }
2221 
2222 // ===========================================================================
2223 // protected
2224 // ===========================================================================
2225 
2226 GNEJunction*
2227 GNERouteHandler::parseJunction(const SumoXMLTag tag, const std::string& junctionID) {
2228  GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(junctionID, false);
2229  // empty junctions aren't allowed. If junction is empty, write error, clear junctions and stop
2230  if (junction == nullptr) {
2231  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_JUNCTION)));
2232  }
2233  return junction;
2234 }
2235 
2236 
2238 GNERouteHandler::parseTAZ(const SumoXMLTag tag, const std::string& TAZID) {
2240  // empty TAZs aren't allowed. If TAZ is empty, write error, clear TAZs and stop
2241  if (TAZ == nullptr) {
2242  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_TAZ)));
2243  }
2244  return TAZ;
2245 }
2246 
2247 
2248 GNEEdge*
2249 GNERouteHandler::parseEdge(const SumoXMLTag tag, const std::string& edgeID) {
2250  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2251  // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2252  if (edge == nullptr) {
2253  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2254  }
2255  return edge;
2256 }
2257 
2258 
2259 std::vector<GNEEdge*>
2260 GNERouteHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
2261  std::vector<GNEEdge*> edges;
2262  for (const auto& edgeID : edgeIDs) {
2263  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2264  // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2265  if (edge == nullptr) {
2266  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2267  edges.clear();
2268  return edges;
2269  } else {
2270  edges.push_back(edge);
2271  }
2272  }
2273  return edges;
2274 }
2275 
2276 
2278 GNERouteHandler::getType(const std::string& id) const {
2280  if (type == nullptr) {
2282  } else {
2283  return type;
2284  }
2285 }
2286 
2287 
2290  // check that sumoBaseObject has parent
2291  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2292  return nullptr;
2293  }
2294  if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSON) &&
2295  (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSONFLOW)) {
2296  return nullptr;
2297  }
2298  // try it with person
2300  // if empty, try it with personFlow
2301  if (personParent == nullptr) {
2303  } else {
2304  return personParent;
2305  }
2306 }
2307 
2308 
2311  // check that sumoBaseObject has parent
2312  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2313  return nullptr;
2314  }
2315  if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINER) &&
2316  (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2317  return nullptr;
2318  }
2319  // try it with container
2321  // if empty, try it with containerFlow
2322  if (containerParent == nullptr) {
2324  } else {
2325  return containerParent;
2326  }
2327 }
2328 
2329 
2330 bool
2332  const std::vector<std::string>& distributionElementIDs, const std::vector<double>& probabilities,
2333  std::vector<const GNEDemandElement*>& elements) {
2334  // get distribution tag and ID
2335  std::string distributionTag = toString(sumoBaseObject->getTag());
2336  std::string distributionID = sumoBaseObject->getStringAttribute(SUMO_ATTR_ID);
2337  // first parse vType IDs
2338  for (const auto& distributionElementID : distributionElementIDs) {
2339  auto distributionElement = myNet->getAttributeCarriers()->retrieveDemandElement(distributionElementTag, distributionElementID, false);
2340  if (distributionElement) {
2341  elements.push_back(distributionElement);
2342  } else {
2343  writeError(TLF("% with id '%' doesn't exist in % '%'", toString(distributionElementTag), distributionElementID, distributionTag, distributionID));
2344  return false;
2345 
2346  }
2347  }
2348  // check probabilities
2349  for (const auto& probability : probabilities) {
2350  if (probability < 0) {
2351  writeError(TLF("invalid probability % in % '%'", toString(probability), distributionTag, distributionID));
2352  return false;
2353  }
2354  }
2355  // check that number of elements and probabilities is the same
2356  if (elements.size() != probabilities.size()) {
2357  writeError(TLF("Invalid type distribution probabilities in % '%'. Must have the same number of elements", distributionTag, distributionID));
2358  return false;
2359  } else {
2360  return true;
2361  }
2362 }
2363 
2364 
2365 bool
2367  // retrieve demand element
2368  auto demandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false);
2369  // if demand exist, check if overwrite (delete)
2370  if (demandElement) {
2371  if (!myAllowUndoRedo) {
2372  // only overwrite if allow undo-redo
2373  return false;
2374  } else if (myOverwrite) {
2375  // update demand to overwrite
2376  myDemandToOverwrite = demandElement;
2377  return true;
2378  } else {
2379  // duplicated demand
2380  return false;
2381  }
2382  } else {
2383  // demand with these id doesn't exist, then all ok
2384  return true;
2385  }
2386 }
2387 
2388 
2389 void
2391  if (myDemandToOverwrite) {
2392  // remove element
2394  // reset pointer
2395  myDemandToOverwrite = nullptr;
2396  }
2397 }
2398 
2399 /****************************************************************************/
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
@ 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_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ GNE_TAG_STOP_BUSSTOP
stop placed over a busStop
@ SUMO_TAG_CONTAINERFLOW
@ GNE_TAG_WAYPOINT_TRAINSTOP
@ GNE_TAG_WAYPOINT_CONTAINERSTOP
@ GNE_TAG_WAYPOINT_BUSSTOP
@ SUMO_TAG_BUS_STOP
A bus stop.
@ GNE_TAG_WAYPOINT_CHARGINGSTATION
@ GNE_TAG_STOPPERSON_BUSSTOP
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ GNE_TAG_FLOW_JUNCTIONS
a flow between junctions
@ GNE_TAG_STOP_CONTAINERSTOP
stop placed over a containerStop
@ GNE_TAG_STOPCONTAINER_CONTAINERSTOP
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ 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
@ 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
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_LINES
@ GNE_ATTR_FROM_TRAINSTOP
@ SUMO_ATTR_NUMBER
@ GNE_ATTR_FROM_BUSSTOP
@ 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_GROUP
@ GNE_ATTR_FROM_CONTAINERSTOP
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_PROB
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_WALKFACTOR
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_PERSONSPERHOUR
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition: Boundary.cpp:172
plan parameters (used for group all from-to parameters related with plans)
std::string fromJunction
from junction
std::string fromContainerStop
from containerStop
std::string toTrainStop
to trainStop
std::string fromTrainStop
from trainStop
std::string fromBusStop
from busStop
std::vector< std::string > consecutiveEdges
consecutive edges
std::string toContainerStop
to containerStop
const SUMOVehicleParameter::Stop & getStopParameter() const
get stop parameters
SUMOTime getTimeAttribute(const SumoXMLAttr attr) const
get time attribute
bool hasBoolAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given bool attribute
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
void setTag(const SumoXMLTag tag)
set SumoBaseObject tag
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
bool hasTimeAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given time attribute
void addBoolAttribute(const SumoXMLAttr attr, const bool value)
add bool attribute into current SumoBaseObject node
SumoXMLTag getTag() const
get XML myTag
void addTimeAttribute(const SumoXMLAttr attr, const SUMOTime value)
add time attribute into current SumoBaseObject node
void addStringListAttribute(const SumoXMLAttr attr, const std::vector< std::string > &value)
add string list attribute into current SumoBaseObject node
void addDoubleAttribute(const SumoXMLAttr attr, const double value)
add double attribute into current SumoBaseObject node
bool hasDoubleAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given double attribute
bool getBoolAttribute(const SumoXMLAttr attr) const
get bool attribute
void setVehicleParameter(const SUMOVehicleParameter *vehicleParameter)
set vehicle parameters
void addStringAttribute(const SumoXMLAttr attr, const std::string &value)
add string attribute into current SumoBaseObject node
double getDoubleAttribute(const SumoXMLAttr attr) const
get double attribute
const SUMOVehicleParameter & getVehicleParameter() const
get vehicle parameters
const std::vector< std::string > & getStringListAttribute(const SumoXMLAttr attr) const
get string list attribute
bool hasStringListAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given string list attribute
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
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 > getPersonTripTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the personTrip tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getContainerStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the container stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getRideTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the ride tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getPersonStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the person stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getWalkTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the walk tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTranshipTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the tranship tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTransportTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the transport tag and icon for the combination
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
void addChildElement(T *element)
add child element
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
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:675
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:123
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:135
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2136
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
double getClickedPositionOverLane() const
get clicked position over lane
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
GNEPlanParents (used for group all plan parents)
void addChildElements(GNEDemandElement *element)
add the given element in the element as child
bool checkIntegrity(SumoXMLTag planTag, const GNEDemandElement *parent, const CommonXMLStructure::PlanParameters &planParameters) const
check integrity between planParameters and GNE elements
void incRef(const std::string &debugMsg="")
Increase reference.
Builds trigger objects for GNENet (busStops, chargingStations, detectors, etc..)
void buildTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeID)
build trip
void buildPersonStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build person stop
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 buildPersonTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &types, const std::vector< std::string > &modes, const std::vector< std::string > &lines, const double walkFactor, const std::string &group)
build person trip
static void transformToRouteFlow(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform routeFlow over an existent route
GNENet * myNet
pointer to GNENet
void duplicatePlan(const GNEDemandElement *originalPlan, GNEDemandElement *newParent)
duplicate given plan in new parent
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
void buildWalk(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const double speed, const SUMOTime duration)
build walk
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 buildContainerStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build container stop
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
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
static void transformToTrip(GNEVehicle *originalVehicle)
transform to trip
void buildRouteDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::vector< std::string > &routeIDs, const std::vector< double > &probabilities)
build route distribution
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
void buildRide(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &lines, const std::string &group)
build ride
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 buildTranship(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPosition, const double departPosition, const double speed, const SUMOTime duration)
build tranship
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
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::vector< std::string > &edgeIDs)
parse edges
void buildTransport(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &lines, const std::string &group)
build transport
void buildStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const SUMOVehicleParameter::Stop &stopParameters)
build stop
GNEDemandElement * getContainerParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get container parent
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 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.
static void transformToVehicle(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform vehicle functions
static void transformToTripTAZs(GNEVehicle *originalVehicle)
transform to trip over TAZs
static GNEDemandElement * copyRoute(const GNERoute *originalRoute)
create a copy of the given route
Definition: GNERoute.cpp:706
bool isPlanTransport() const
return true if tag correspond to a transport
bool isContainer() const
return true if tag correspond to a container element
bool isFlow() const
return true if tag correspond to a flow element
bool isVehicle() const
return true if tag correspond to a vehicle element
bool vehicleJunctions() const
return true if tag correspond to a vehicle placed over from-to junctions
bool isPlanStopContainer() const
return true if tag correspond to a container stop plan
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool vehicleRouteEmbedded() const
return true if tag correspond to a vehicle placed over an embedded route
bool isPlanPersonTrip() const
return true if tag correspond to a person trip plan
bool vehicleEdges() const
return true if tag correspond to a vehicle placed over from-to edges
bool isPlanRide() const
return true if tag correspond to a ride plan
bool isPlanStopPerson() const
return true if tag correspond to a person stop plan
bool isPerson() const
return true if tag correspond to a person element
bool vehicleTAZs() const
return true if tag correspond to a vehicle placed over from-to TAZs
bool vehicleRoute() const
plan parents
bool isPlanWalk() const
return true if tag correspond to a walk plan
bool isPlanTranship() const
return true if tag correspond to a tranship
GNEAttributeCarrier * getTemplateAC(SumoXMLTag ACTag) const
get templateAC
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
static 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
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.