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.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
15 // Builds demand objects for netedit
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEUndoList.h>
24 #include <netedit/GNEViewNet.h>
30 
31 #include "GNEPerson.h"
32 #include "GNEPersonTrip.h"
33 #include "GNERide.h"
34 #include "GNERoute.h"
35 #include "GNERouteHandler.h"
36 #include "GNEStop.h"
37 #include "GNEVehicle.h"
38 #include "GNEVehicleType.h"
39 #include "GNEWalk.h"
40 
41 
42 // ===========================================================================
43 // member method definitions
44 // ===========================================================================
45 
46 // ---------------------------------------------------------------------------
47 // GNERouteHandler::RouteParameter - methods
48 // ---------------------------------------------------------------------------
49 
51  VClass(SVC_PASSENGER) {
52 }
53 
54 
56  routeID(originalDemandElement->getTagProperty().isRoute() ?
57  originalDemandElement->getID() :
58  originalDemandElement->getViewNet()->getNet()->generateDemandElementID(originalDemandElement->getID(), SUMO_TAG_ROUTE)),
59  edges(originalDemandElement->getEdgeParents()),
60  color(originalDemandElement->getColor()),
61  VClass(originalDemandElement->getVClass()) {
62 }
63 
64 
65 void
66 GNERouteHandler::RouteParameter::setEdges(GNEViewNet* viewNet, const std::string& edgeIDs) {
67  // clear edges
68  edges.clear();
69  // obtain edges (And show warnings if isn't valid)
70  if (GNEAttributeCarrier::canParse<std::vector<GNEEdge*> >(viewNet->getNet(), edgeIDs, true)) {
71  edges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(viewNet->getNet(), edgeIDs);
72  }
73 }
74 
75 
76 void
77 GNERouteHandler::RouteParameter::setEdges(GNEViewNet* viewNet, const std::string& vehicleID, const std::string& fromID, const std::string& toID, const std::string& viaIDs) {
78  // clear edges
79  edges.clear();
80  // only continue if at least one of the edges is defined
81  if (fromID.size() + toID.size() > 0) {
82  // obtain from and to edges
83  GNEEdge* from = viewNet->getNet()->retrieveEdge(fromID, false);
84  GNEEdge* to = viewNet->getNet()->retrieveEdge(toID, false);
85  // check if edges are valid
86  if (from == nullptr) {
87  WRITE_ERROR("Invalid 'from' edge used in trip '" + vehicleID + "'.");
88  } else if (to == nullptr) {
89  WRITE_ERROR("Invalid 'to' edge used in trip '" + vehicleID + "'.");
90  } else if (!GNEAttributeCarrier::canParse<std::vector<GNEEdge*> >(viewNet->getNet(), viaIDs, false)) {
91  WRITE_ERROR("Invalid 'via' edges used in trip '" + vehicleID + "'.");
92  } else {
93  // obtain via
94  std::vector<GNEEdge*> viaEdges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(viewNet->getNet(), viaIDs);
95  // build edges (from - via - to)
96  edges.push_back(from);
97  for (const auto& i : viaEdges) {
98  edges.push_back(i);
99  }
100  // check that from and to edge are different
101  if (from != to) {
102  edges.push_back(to);
103  }
104  }
105  }
106 }
107 
108 // ---------------------------------------------------------------------------
109 // GNERouteHandler - methods
110 // ---------------------------------------------------------------------------
111 
112 GNERouteHandler::GNERouteHandler(const std::string& file, GNEViewNet* viewNet, bool undoDemandElements) :
113  SUMORouteHandler(file, "", false),
114  myViewNet(viewNet),
115  myUndoDemandElements(undoDemandElements) {
116 }
117 
118 
120 
121 
122 bool
123 GNERouteHandler::isVehicleIdDuplicated(GNEViewNet* viewNet, const std::string& id) {
124  for (SumoXMLTag vehicleTag : std::vector<SumoXMLTag>({SUMO_TAG_VEHICLE, SUMO_TAG_TRIP, SUMO_TAG_ROUTEFLOW, SUMO_TAG_FLOW})) {
125  if (viewNet->getNet()->retrieveDemandElement(vehicleTag, id, false) != nullptr) {
126  WRITE_ERROR("There is another " + toString(vehicleTag) + " with the same ID='" + id + "'.");
127  return true;
128  }
129  }
130  return false;
131 }
132 
133 
134 bool
135 GNERouteHandler::isPersonIdDuplicated(GNEViewNet* viewNet, const std::string& id) {
136  for (SumoXMLTag personTag : std::vector<SumoXMLTag>({SUMO_TAG_PERSON, SUMO_TAG_PERSONFLOW})) {
137  if (viewNet->getNet()->retrieveDemandElement(personTag, id, false) != nullptr) {
138  WRITE_ERROR("There is another " + toString(personTag) + " with the same ID='" + id + "'.");
139  return true;
140  }
141  }
142  return false;
143 }
144 
145 
146 void
147 GNERouteHandler::buildVehicleOverRoute(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& vehicleParameters) {
148  // Check tag
149  assert(vehicleParameters.tag == SUMO_TAG_VEHICLE);
150  // first check if ID is duplicated
151  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
152  // obtain routes and vtypes
153  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
154  GNEDemandElement* route = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_ROUTE, vehicleParameters.routeid, false);
155  if (vType == nullptr) {
156  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
157  } else if (route == nullptr) {
158  WRITE_ERROR("Invalid route '" + vehicleParameters.routeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
159  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN) && ((int)route->getEdgeParents().front()->getLanes().size() < vehicleParameters.departLane)) {
160  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
161  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
162  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
163  } else {
164  // create vehicle using vehicleParameters
165  GNEVehicle* vehicle = new GNEVehicle(viewNet, vType, route, vehicleParameters);
166  if (undoDemandElements) {
167  viewNet->getUndoList()->p_begin("add " + vehicle->getTagStr());
168  viewNet->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
169  // iterate over stops of vehicleParameters and create stops associated with it
170  for (const auto& i : vehicleParameters.stops) {
171  buildStop(viewNet, true, i, vehicle, false);
172  }
173  viewNet->getUndoList()->p_end();
174  } else {
175  viewNet->getNet()->insertDemandElement(vehicle);
176  // set vehicle as child of vType and Route
177  vType->addDemandElementChild(vehicle);
178  route->addDemandElementChild(vehicle);
179  vehicle->incRef("buildVehicleOverRoute");
180  // iterate over stops of vehicleParameters and create stops associated with it
181  for (const auto& i : vehicleParameters.stops) {
182  buildStop(viewNet, false, i, vehicle, false);
183  }
184  }
185  }
186  }
187 }
188 
189 
190 void
191 GNERouteHandler::buildFlowOverRoute(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& vehicleParameters) {
192  // Check tag
193  assert(vehicleParameters.tag == SUMO_TAG_ROUTEFLOW);
194  // first check if ID is duplicated
195  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
196  // obtain routes and vtypes
197  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
198  GNEDemandElement* route = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_ROUTE, vehicleParameters.routeid, false);
199  if (vType == nullptr) {
200  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
201  } else if (route == nullptr) {
202  WRITE_ERROR("Invalid route '" + vehicleParameters.routeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
203  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN) && ((int)route->getEdgeParents().front()->getLanes().size() < vehicleParameters.departLane)) {
204  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
205  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
206  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
207  } else {
208  // create flow or trips using vehicleParameters
209  GNEVehicle* flow = new GNEVehicle(viewNet, vType, route, vehicleParameters);
210  if (undoDemandElements) {
211  viewNet->getUndoList()->p_begin("add " + flow->getTagStr());
212  viewNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
213  // iterate over stops of vehicleParameters and create stops associated with it
214  for (const auto& i : vehicleParameters.stops) {
215  buildStop(viewNet, true, i, flow, false);
216  }
217  viewNet->getUndoList()->p_end();
218  } else {
219  viewNet->getNet()->insertDemandElement(flow);
220  // set flow as child of vType and Route
221  vType->addDemandElementChild(flow);
222  route->addDemandElementChild(flow);
223  flow->incRef("buildFlowOverRoute");
224  // iterate over stops of vehicleParameters and create stops associated with it
225  for (const auto& i : vehicleParameters.stops) {
226  buildStop(viewNet, false, i, flow, false);
227  }
228  }
229  }
230  }
231 }
232 
233 
234 void
235 GNERouteHandler::buildVehicleWithEmbeddedRoute(GNEViewNet* viewNet, bool undoDemandElements, SUMOVehicleParameter vehicleParameters, GNEDemandElement* embeddedRouteCopy) {
236  // Check tags
237  assert(vehicleParameters.tag == SUMO_TAG_VEHICLE);
238  // first check if ID is duplicated
239  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
240  // obtain vType
241  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
242  if (vType == nullptr) {
243  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
244  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN) && ((int)embeddedRouteCopy->getEdgeParents().front()->getLanes().size() < vehicleParameters.departLane)) {
245  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
246  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
247  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
248  } else {
249  // generate a new route ID and add it to vehicleParameters
250  vehicleParameters.routeid = viewNet->getNet()->generateDemandElementID(vehicleParameters.id, SUMO_TAG_ROUTE);
251  // due vehicle was loaded without a route, change tag
252  vehicleParameters.tag = SUMO_TAG_VEHICLE;
253  // create vehicle or trips using myTemporalVehicleParameter without a route
254  GNEVehicle* vehicle = new GNEVehicle(viewNet, vType, vehicleParameters);
255  // creaste embedded route
256  GNERoute* embeddedRoute = new GNERoute(viewNet, vehicle, RouteParameter(embeddedRouteCopy));
257  // add both to net depending of myUndoDemandElements
258  if (undoDemandElements) {
259  viewNet->getUndoList()->p_begin("add vehicle and " + embeddedRoute->getTagStr());
260  // add both in net using undoList
261  viewNet->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
262  viewNet->getUndoList()->add(new GNEChange_DemandElement(embeddedRoute, true), true);
263  viewNet->getUndoList()->p_end();
264  } else {
265  // add vehicleOrRouteFlow in net and in their vehicle type parent
266  viewNet->getNet()->insertDemandElement(vehicle);
267  // set vehicle as child of vType
268  vType->addDemandElementChild(vehicle);
269  vehicle->incRef("buildVehicleWithEmbeddedRoute");
270  // add route manually in net, and in all of their edges and in vehicleOrRouteFlow
271  viewNet->getNet()->insertDemandElement(embeddedRoute);
272  for (const auto& i : embeddedRouteCopy->getEdgeParents()) {
273  i->addDemandElementChild(vehicle);
274  }
275  // set route as child of vehicle
276  vehicle->addDemandElementChild(embeddedRoute);
277  embeddedRoute->incRef("buildVehicleWithEmbeddedRoute");
278  }
279  }
280  }
281 }
282 
283 
284 void
285 GNERouteHandler::buildFlowWithEmbeddedRoute(GNEViewNet* viewNet, bool undoDemandElements, SUMOVehicleParameter vehicleParameters, GNEDemandElement* embeddedRouteCopy) {
286  // Check tags
287  assert(vehicleParameters.tag == SUMO_TAG_ROUTEFLOW);
288  // first check if ID is duplicated
289  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
290  // obtain vType
291  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
292  if (vType == nullptr) {
293  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
294  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN) && ((int)embeddedRouteCopy->getEdgeParents().front()->getLanes().size() < vehicleParameters.departLane)) {
295  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
296  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
297  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
298  } else {
299  // generate a new route ID and add it to vehicleParameters
300  vehicleParameters.routeid = viewNet->getNet()->generateDemandElementID(vehicleParameters.id, SUMO_TAG_ROUTE);
301  // due vehicle was loaded without a route, change tag
302  vehicleParameters.tag = SUMO_TAG_ROUTEFLOW;
303  // create vehicle or trips using myTemporalVehicleParameter without a route
304  GNEVehicle* flow = new GNEVehicle(viewNet, vType, vehicleParameters);
305  // creaste embedded route
306  GNERoute* embeddedRoute = new GNERoute(viewNet, flow, RouteParameter(embeddedRouteCopy));
307  // add both to net depending of myUndoDemandElements
308  if (undoDemandElements) {
309  viewNet->getUndoList()->p_begin("add vehicle and " + embeddedRoute->getTagStr());
310  // add both in net using undoList
311  viewNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
312  viewNet->getUndoList()->add(new GNEChange_DemandElement(embeddedRoute, true), true);
313  viewNet->getUndoList()->p_end();
314  } else {
315  // add vehicleOrRouteFlow in net and in their vehicle type parent
316  viewNet->getNet()->insertDemandElement(flow);
317  // set vehicle as child of vType
318  vType->addDemandElementChild(flow);
319  flow->incRef("buildFlowWithEmbeddedRoute");
320  // add route manually in net, and in all of their edges and in vehicleOrRouteFlow
321  viewNet->getNet()->insertDemandElement(embeddedRoute);
322  for (const auto& i : embeddedRouteCopy->getEdgeParents()) {
323  i->addDemandElementChild(flow);
324  }
325  // set route as child of flow
326  flow->addDemandElementChild(embeddedRoute);
327  embeddedRoute->incRef("buildFlowWithEmbeddedRoute");
328  }
329  }
330  }
331 }
332 
333 
334 void
335 GNERouteHandler::buildTrip(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& vehicleParameters, const std::vector<GNEEdge*>& edges) {
336  // Check tag
337  assert(vehicleParameters.tag == SUMO_TAG_TRIP);
338  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
339  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
340  // obtain vtypes
341  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
342  if (vType == nullptr) {
343  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
344  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN)) && ((int)edges.front()->getLanes().size() < vehicleParameters.departLane)) {
345  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
346  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
347  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
348  } else {
349  // add "via" edges in vehicleParameters
350  for (int i = 1; i < ((int)edges.size() - 1); i++) {
351  vehicleParameters.via.push_back(edges.at(i)->getID());
352  }
353  // create trip or flow using tripParameters
354  GNEVehicle* trip = new GNEVehicle(viewNet, vType, edges.front(), edges.back(), vehicleParameters);
355  if (undoDemandElements) {
356  viewNet->getUndoList()->p_begin("add " + trip->getTagStr());
357  viewNet->getUndoList()->add(new GNEChange_DemandElement(trip, true), true);
358  // iterate over stops of vehicleParameters and create stops associated with it
359  for (const auto& i : vehicleParameters.stops) {
360  buildStop(viewNet, true, i, trip, false);
361  }
362  viewNet->getUndoList()->p_end();
363  } else {
364  viewNet->getNet()->insertDemandElement(trip);
365  // set vehicle as child of vType
366  vType->addDemandElementChild(trip);
367  trip->incRef("buildTrip");
368  // add reference in all edges
369  for (const auto& i : edges) {
370  i->addDemandElementChild(trip);
371  }
372  // iterate over stops of vehicleParameters and create stops associated with it
373  for (const auto& i : vehicleParameters.stops) {
374  buildStop(viewNet, false, i, trip, false);
375  }
376  }
377  }
378  }
379 }
380 
381 
382 void
383 GNERouteHandler::buildFlow(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& vehicleParameters, const std::vector<GNEEdge*>& edges) {
384  // Check tag
385  assert(vehicleParameters.tag == SUMO_TAG_FLOW);
386  // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
387  if (!isVehicleIdDuplicated(viewNet, vehicleParameters.id)) {
388  // obtain vtypes
389  GNEDemandElement* vType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameters.vtypeid, false);
390  if (vType == nullptr) {
391  WRITE_ERROR("Invalid vehicle type '" + vehicleParameters.vtypeid + "' used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'.");
392  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DEPART_LANE_GIVEN) && ((int)edges.front()->getLanes().size() < vehicleParameters.departLane)) {
393  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTLANE) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departLane) + " is greater than number of lanes");
394  } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DEPART_SPEED_GIVEN) && (vType->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
395  WRITE_ERROR("Invalid " + toString(SUMO_ATTR_DEPARTSPEED) + " used in " + toString(vehicleParameters.tag) + " '" + vehicleParameters.id + "'. " + toString(vehicleParameters.departSpeed) + " is greater than vType" + toString(SUMO_ATTR_MAXSPEED));
396  } else {
397  // add "via" edges in vehicleParameters
398  for (int i = 1; i < ((int)edges.size() - 1); i++) {
399  vehicleParameters.via.push_back(edges.at(i)->getID());
400  }
401  // create trip or flow using tripParameters
402  GNEVehicle* flow = new GNEVehicle(viewNet, vType, edges.front(), edges.back(), vehicleParameters);
403  if (undoDemandElements) {
404  viewNet->getUndoList()->p_begin("add " + flow->getTagStr());
405  viewNet->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
406  // iterate over stops of vehicleParameters and create stops associated with it
407  for (const auto& i : vehicleParameters.stops) {
408  buildStop(viewNet, true, i, flow, false);
409  }
410  viewNet->getUndoList()->p_end();
411  } else {
412  viewNet->getNet()->insertDemandElement(flow);
413  // set vehicle as child of vType
414  vType->addDemandElementChild(flow);
415  flow->incRef("buildFlow");
416  // add reference in all edges
417  for (const auto& i : edges) {
418  i->addDemandElementChild(flow);
419  }
420  // iterate over stops of vehicleParameters and create stops associated with it
421  for (const auto& i : vehicleParameters.stops) {
422  buildStop(viewNet, false, i, flow, false);
423  }
424  }
425  }
426  }
427 }
428 
429 
430 void
431 GNERouteHandler::buildStop(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter::Stop& stopParameters, GNEDemandElement* stopParent, bool friendlyPosition) {
432  // declare pointers to stopping place and lane and obtain it
433  GNEAdditional* stoppingPlace = nullptr;
434  GNELane* lane = nullptr;
435  SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
436  bool validDemandElementParent = true;
437  if (stopParameters.busstop.size() > 0) {
438  stoppingPlace = viewNet->getNet()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
439  // distinguish between stop for vehicles and stops for persons
440  if (stopParent->getTagProperty().isPerson()) {
441  stopTagType = SUMO_TAG_PERSONSTOP_BUSSTOP;
442  } else {
443  stopTagType = SUMO_TAG_STOP_BUSSTOP;
444  }
445  } else if (stopParameters.containerstop.size() > 0) {
446  stoppingPlace = viewNet->getNet()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
447  // distinguish between stop for vehicles and stops for persons
448  if (stopParent->getTagProperty().isPerson()) {
449  WRITE_ERROR("Persons doesn't support stops over container stops");
450  validDemandElementParent = false;
451  } else {
452  stopTagType = SUMO_TAG_STOP_CONTAINERSTOP;
453  }
454  } else if (stopParameters.chargingStation.size() > 0) {
455  stoppingPlace = viewNet->getNet()->retrieveAdditional(SUMO_TAG_CHARGING_STATION, stopParameters.chargingStation, false);
456  // distinguish between stop for vehicles and stops for persons
457  if (stopParent->getTagProperty().isPerson()) {
458  WRITE_ERROR("Persons doesn't support stops over charging stations");
459  validDemandElementParent = false;
460  } else {
461  stopTagType = SUMO_TAG_STOP_CHARGINGSTATION;
462  }
463  } else if (stopParameters.parkingarea.size() > 0) {
464  stoppingPlace = viewNet->getNet()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
465  // distinguish between stop for vehicles and stops for persons
466  if (stopParent->getTagProperty().isPerson()) {
467  WRITE_ERROR("Persons doesn't support stops over parking areas");
468  validDemandElementParent = false;
469  } else {
470  stopTagType = SUMO_TAG_STOP_PARKINGAREA;
471  }
472  } else if (stopParameters.lane.size() > 0) {
473  lane = viewNet->getNet()->retrieveLane(stopParameters.lane, false);
474  // distinguish between stop for vehicles and stops for persons
475  if (stopParent->getTagProperty().isPerson()) {
476  stopTagType = SUMO_TAG_PERSONSTOP_LANE;
477  } else {
478  stopTagType = SUMO_TAG_STOP_LANE;
479  }
480  }
481  // first check that parent is valid
482  if (validDemandElementParent) {
483  // check if values are correct
484  if (stoppingPlace && lane) {
485  WRITE_ERROR("A stop must be defined either over a stoppingPlace or over a lane");
486  } else if (!stoppingPlace && !lane) {
487  WRITE_ERROR("A stop requires a stoppingPlace or a lane");
488  } else if (stoppingPlace) {
489  // create stop using stopParameters and stoppingPlace
490  GNEStop* stop = new GNEStop(stopTagType, viewNet, stopParameters, stoppingPlace, stopParent);
491  // add it depending of undoDemandElements
492  if (undoDemandElements) {
493  viewNet->getUndoList()->p_begin("add " + stop->getTagStr());
494  viewNet->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
495  viewNet->getUndoList()->p_end();
496  } else {
497  viewNet->getNet()->insertDemandElement(stop);
498  stoppingPlace->addDemandElementChild(stop);
499  stopParent->addDemandElementChild(stop);
500  stop->incRef("buildStoppingPlaceStop");
501  }
502  } else {
503  // create stop using stopParameters and lane
504  GNEStop* stop = new GNEStop(viewNet, stopParameters, lane, friendlyPosition, stopParent);
505  // add it depending of undoDemandElements
506  if (undoDemandElements) {
507  viewNet->getUndoList()->p_begin("add " + stop->getTagStr());
508  viewNet->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
509  viewNet->getUndoList()->p_end();
510  } else {
511  viewNet->getNet()->insertDemandElement(stop);
512  lane->addDemandElementChild(stop);
513  stopParent->addDemandElementChild(stop);
514  stop->incRef("buildLaneStop");
515  }
516  }
517  }
518 }
519 
520 
521 void
522 GNERouteHandler::buildPerson(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& personParameters) {
523  // first check if ID is duplicated
524  if (!isPersonIdDuplicated(viewNet, personParameters.id)) {
525  // obtain routes and vtypes
526  GNEDemandElement* pType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_PTYPE, personParameters.vtypeid, false);
527  if (pType == nullptr) {
528  WRITE_ERROR("Invalid person type '" + personParameters.vtypeid + "' used in " + toString(personParameters.tag) + " '" + personParameters.id + "'.");
529  } else {
530  // create person using personParameters
531  GNEPerson* person = new GNEPerson(SUMO_TAG_PERSON, viewNet, pType, personParameters);
532  if (undoDemandElements) {
533  viewNet->getUndoList()->p_begin("add " + person->getTagStr());
534  viewNet->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
535  viewNet->getUndoList()->p_end();
536  } else {
537  viewNet->getNet()->insertDemandElement(person);
538  // set person as child of pType and Route
539  pType->addDemandElementChild(person);
540  person->incRef("buildPerson");
541  }
542  }
543  }
544 }
545 
546 
547 void
548 GNERouteHandler::buildPersonFlow(GNEViewNet* viewNet, bool undoDemandElements, const SUMOVehicleParameter& personFlowParameters) {
549  // first check if ID is duplicated
550  if (!isPersonIdDuplicated(viewNet, personFlowParameters.id)) {
551  // obtain routes and vtypes
552  GNEDemandElement* pType = viewNet->getNet()->retrieveDemandElement(SUMO_TAG_PTYPE, personFlowParameters.vtypeid, false);
553  if (pType == nullptr) {
554  WRITE_ERROR("Invalid personFlow type '" + personFlowParameters.vtypeid + "' used in " + toString(personFlowParameters.tag) + " '" + personFlowParameters.id + "'.");
555  } else {
556  // create personFlow using personFlowParameters
557  GNEPerson* personFlow = new GNEPerson(SUMO_TAG_PERSONFLOW, viewNet, pType, personFlowParameters);
558  if (undoDemandElements) {
559  viewNet->getUndoList()->p_begin("add " + personFlow->getTagStr());
560  viewNet->getUndoList()->add(new GNEChange_DemandElement(personFlow, true), true);
561  viewNet->getUndoList()->p_end();
562  } else {
563  viewNet->getNet()->insertDemandElement(personFlow);
564  // set personFlow as child of pType and Route
565  pType->addDemandElementChild(personFlow);
566  personFlow->incRef("buildPersonFlow");
567  }
568  }
569  }
570 }
571 
572 
573 void
574 GNERouteHandler::buildPersonTripFromTo(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges,
575  const std::vector<std::string>& types, const std::vector<std::string>& modes, double arrivalPos) {
576  // check that at least there is an edge
577  if (edges.size() == 0) {
578  WRITE_ERROR("A personTrip needs at least one edge. " + toString(SUMO_TAG_PERSONTRIP_FROMTO) + " within person with ID='" + personParent->getID() + "' cannot be created");
579  } else {
580  // obtain path between edges
581  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(personParent->getVClass(), edges);
582  // check if obtained path is valid
583  if (pathEdges.size() == 0) {
584  pathEdges = edges;
585  }
586  // create personTripFromTo
587  GNEPersonTrip* personTripFromTo = new GNEPersonTrip(viewNet, personParent, pathEdges, types, modes, arrivalPos);
588  // add element using undo list or directly, depending of undoDemandElements flag
589  if (undoDemandElements) {
590  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_PERSONTRIP_FROMTO) + " within person '" + personParent->getID() + "'");
591  viewNet->getUndoList()->add(new GNEChange_DemandElement(personTripFromTo, true), true);
592  viewNet->getUndoList()->p_end();
593  } else {
594  // add vehicleOrPersonTripFlow in net and in their vehicle type parent
595  viewNet->getNet()->insertDemandElement(personTripFromTo);
596  personParent->addDemandElementChild(personTripFromTo);
597  personTripFromTo->incRef("buildPersonTripFromTo");
598  }
599  // mark geometry of person plan parent deprecated and update geometry
600  personParent->markSegmentGeometryDeprecated();
601  personParent->updateGeometry();
602  }
603 }
604 
605 
606 void
607 GNERouteHandler::buildPersonTripBusStop(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges,
608  GNEAdditional* busStop, const std::vector<std::string>& types, const std::vector<std::string>& modes) {
609  // check that at least there is an edge
610  if (edges.size() == 0) {
611  WRITE_ERROR("A personTrip needs at least one edge. " + toString(SUMO_TAG_PERSONTRIP_BUSSTOP) + " within person with ID='" + personParent->getID() + "' cannot be created");
612  } else {
613  // obtain path between edges
614  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(personParent->getVClass(), edges);
615  // check if obtained path is valid
616  if (pathEdges.size() == 0) {
617  pathEdges = edges;
618  }
619  // create personTripBusStop
620  GNEPersonTrip* personTripBusStop = new GNEPersonTrip(viewNet, personParent, pathEdges, busStop, types, modes);
621  // add element using undo list or directly, depending of undoDemandElements flag
622  if (undoDemandElements) {
623  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_PERSONTRIP_BUSSTOP) + " within person '" + personParent->getID() + "'");
624  viewNet->getUndoList()->add(new GNEChange_DemandElement(personTripBusStop, true), true);
625  viewNet->getUndoList()->p_end();
626  } else {
627  // add vehicleOrPersonTripFlow in net and in their vehicle type parent
628  viewNet->getNet()->insertDemandElement(personTripBusStop);
629  personParent->addDemandElementChild(personTripBusStop);
630  busStop->addDemandElementChild(personTripBusStop);
631  // add reference in all edges
632  for (const auto& i : edges) {
633  i->addDemandElementChild(personTripBusStop);
634  }
635  personTripBusStop->incRef("buildPersonTripBusStop");
636  }
637  // mark geometry of person plan parent deprecated and update geometry
638  personParent->markSegmentGeometryDeprecated();
639  personParent->updateGeometry();
640  }
641 }
642 
643 
644 void
645 GNERouteHandler::buildWalkEdges(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges, double arrivalPos) {
646  // check that at least there is an edge
647  if (edges.size() == 0) {
648  WRITE_ERROR("A walk needs at least one edge. " + toString(SUMO_TAG_WALK_EDGES) + " within person with ID='" + personParent->getID() + "' cannot be created");
649  } else {
650  // obtain path between edges
651  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(personParent->getVClass(), edges);
652  // check if obtained path is valid
653  if (pathEdges.size() == 0) {
654  pathEdges = edges;
655  }
656  // create walkEdges
657  GNEWalk* walkEdges = new GNEWalk(viewNet, personParent, SUMO_TAG_WALK_EDGES, pathEdges, arrivalPos);
658  // add element using undo list or directly, depending of undoDemandElements flag
659  if (undoDemandElements) {
660  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_WALK_EDGES) + " within person '" + personParent->getID() + "'");
661  viewNet->getUndoList()->add(new GNEChange_DemandElement(walkEdges, true), true);
662  viewNet->getUndoList()->p_end();
663  } else {
664  // add vehicleOrWalkEdgesFlow in net and in their vehicle type parent
665  viewNet->getNet()->insertDemandElement(walkEdges);
666  personParent->addDemandElementChild(walkEdges);
667  // add reference in all edges
668  for (const auto& i : edges) {
669  i->addDemandElementChild(walkEdges);
670  }
671  walkEdges->incRef("buildWalkEdges");
672  }
673  // mark geometry of person plan parent deprecated and update geometry
674  personParent->markSegmentGeometryDeprecated();
675  personParent->updateGeometry();
676  }
677 }
678 
679 
680 void
681 GNERouteHandler::buildWalkFromTo(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges, double arrivalPos) {
682  // check that at least there is an edge
683  if (edges.size() == 0) {
684  WRITE_ERROR("A walk needs at least one edge. " + toString(SUMO_TAG_WALK_FROMTO) + " within person with ID='" + personParent->getID() + "' cannot be created");
685  } else {
686  // obtain path between edgespersonParent->markSegmentGeometryDeprecated();
687  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(personParent->getVClass(), edges);
688  // check if obtained path is valid
689  if (pathEdges.size() == 0) {
690  pathEdges = edges;
691  }
692  // create walkFromTo
693  GNEWalk* walkFromTo = new GNEWalk(viewNet, personParent, SUMO_TAG_WALK_FROMTO, pathEdges, arrivalPos);
694  // add element using undo list or directly, depending of undoDemandElements flag
695  if (undoDemandElements) {
696  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_WALK_FROMTO) + " within person '" + personParent->getID() + "'");
697  viewNet->getUndoList()->add(new GNEChange_DemandElement(walkFromTo, true), true);
698  viewNet->getUndoList()->p_end();
699  } else {
700  // add vehicleOrWalkFromToFlow in net and in their vehicle type parent
701  viewNet->getNet()->insertDemandElement(walkFromTo);
702  personParent->addDemandElementChild(walkFromTo);
703  // add reference in all edges
704  for (const auto& i : edges) {
705  i->addDemandElementChild(walkFromTo);
706  }
707  walkFromTo->incRef("buildWalkFromTo");
708  }
709  // mark geometry of person plan parent deprecated and update geometry
710  personParent->markSegmentGeometryDeprecated();
711  personParent->updateGeometry();
712  }
713 }
714 
715 
716 void
717 GNERouteHandler::buildWalkBusStop(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges, GNEAdditional* busStop) {
718  // check that at least there is an edge
719  if (edges.size() == 0) {
720  WRITE_ERROR("A walk needs at least one edge. " + toString(SUMO_TAG_WALK_BUSSTOP) + " within person with ID='" + personParent->getID() + "' cannot be created");
721  } else {
722  // obtain path between edges
723  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(personParent->getVClass(), edges);
724  // check if obtained path is valid
725  if (pathEdges.size() == 0) {
726  pathEdges = edges;
727  }
728  // create walkBusStop
729  GNEWalk* walkBusStop = new GNEWalk(viewNet, personParent, pathEdges, busStop);
730  // add element using undo list or directly, depending of undoDemandElements flag
731  if (undoDemandElements) {
732  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_WALK_BUSSTOP) + " within person '" + personParent->getID() + "'");
733  viewNet->getUndoList()->add(new GNEChange_DemandElement(walkBusStop, true), true);
734  viewNet->getUndoList()->p_end();
735  } else {
736  // add vehicleOrWalkBusStopFlow in net and in their vehicle type parent
737  viewNet->getNet()->insertDemandElement(walkBusStop);
738  personParent->addDemandElementChild(walkBusStop);
739  busStop->addDemandElementChild(walkBusStop);
740  // add reference in all edges
741  for (const auto& i : edges) {
742  i->addDemandElementChild(walkBusStop);
743  }
744  walkBusStop->incRef("buildWalkBusStop");
745  }
746  // mark geometry of person plan parent deprecated and update geometry
747  personParent->markSegmentGeometryDeprecated();
748  personParent->updateGeometry();
749  }
750 }
751 
752 
753 void
754 GNERouteHandler::buildWalkRoute(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, GNEDemandElement* routeParent, double arrivalPos) {
755  // create walkRoute
756  GNEWalk* walkRoute = new GNEWalk(viewNet, personParent, routeParent, arrivalPos);
757  // add element using undo list or directly, depending of undoDemandElements flag
758  if (undoDemandElements) {
759  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_WALK_ROUTE) + " within person '" + personParent->getID() + "'");
760  viewNet->getUndoList()->add(new GNEChange_DemandElement(walkRoute, true), true);
761  viewNet->getUndoList()->p_end();
762  } else {
763  // add vehicleOrWalkBusStopFlow in net and in their vehicle type parent
764  viewNet->getNet()->insertDemandElement(walkRoute);
765  personParent->addDemandElementChild(walkRoute);
766  routeParent->addDemandElementChild(walkRoute);
767  walkRoute->incRef("buildWalkRoute");
768  }
769  // mark geometry of person plan parent deprecated and update geometry
770  personParent->markSegmentGeometryDeprecated();
771  personParent->updateGeometry();
772 }
773 
774 
775 void
776 GNERouteHandler::buildRideFromTo(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges,
777  const std::vector<std::string>& lines, double arrivalPos) {
778  // check that at least there is an edge
779  if (edges.size() == 0) {
780  WRITE_ERROR("A ride needs at least one edge. " + toString(SUMO_TAG_RIDE_FROMTO) + " within person with ID='" + personParent->getID() + "' cannot be created");
781  } else {
782  // obtain path between edges (use SVC_PASSENGER instead SVC_PEDESTRIAN)
783  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(SVC_PASSENGER, edges);
784  // check if obtained path is valid
785  if (pathEdges.size() == 0) {
786  pathEdges = edges;
787  }
788  // create rideFromTo
789  GNERide* rideFromTo = new GNERide(viewNet, personParent, pathEdges, arrivalPos, lines);
790  // add element using undo list or directly, depending of undoDemandElements flag
791  if (undoDemandElements) {
792  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_RIDE_FROMTO) + " within person '" + personParent->getID() + "'");
793  viewNet->getUndoList()->add(new GNEChange_DemandElement(rideFromTo, true), true);
794  viewNet->getUndoList()->p_end();
795  } else {
796  // add vehicleOrRideFromToFlow in net and in their vehicle type parent
797  viewNet->getNet()->insertDemandElement(rideFromTo);
798  personParent->addDemandElementChild(rideFromTo);
799  // add reference in all edges
800  for (const auto& i : edges) {
801  i->addDemandElementChild(rideFromTo);
802  }
803  rideFromTo->incRef("buildRideFromTo");
804  }
805  // mark geometry of person plan parent deprecated and update geometry
806  personParent->markSegmentGeometryDeprecated();
807  personParent->updateGeometry();
808  }
809 }
810 
811 
812 void
813 GNERouteHandler::buildRideBusStop(GNEViewNet* viewNet, bool undoDemandElements, GNEDemandElement* personParent, const std::vector<GNEEdge*>& edges,
814  GNEAdditional* busStop, const std::vector<std::string>& lines) {
815  // check that at least there is an edge
816  if (edges.size() == 0) {
817  WRITE_ERROR("A ride needs at least one edge. " + toString(SUMO_TAG_RIDE_BUSSTOP) + " within person with ID='" + personParent->getID() + "' cannot be created");
818  } else {
819  // obtain path between (use SVC_PASSENGER instead SVC_PEDESTRIAN)
820  std::vector<GNEEdge*> pathEdges = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(SVC_PASSENGER, edges);
821  // check if obtained path is valid
822  if (pathEdges.size() == 0) {
823  pathEdges = edges;
824  }
825  // create rideBusStop
826  GNERide* rideBusStop = new GNERide(viewNet, personParent, pathEdges, busStop, lines);
827  // add element using undo list or directly, depending of undoDemandElements flag
828  if (undoDemandElements) {
829  viewNet->getUndoList()->p_begin("add " + toString(SUMO_TAG_RIDE_BUSSTOP) + " within person '" + personParent->getID() + "'");
830  viewNet->getUndoList()->add(new GNEChange_DemandElement(rideBusStop, true), true);
831  viewNet->getUndoList()->p_end();
832  } else {
833  // add vehicleOrRideBusStopFlow in net and in their vehicle type parent
834  viewNet->getNet()->insertDemandElement(rideBusStop);
835  personParent->addDemandElementChild(rideBusStop);
836  busStop->addDemandElementChild(rideBusStop);
837  // add reference in all edges
838  for (const auto& i : edges) {
839  i->addDemandElementChild(rideBusStop);
840  }
841  rideBusStop->incRef("buildRideBusStop");
842  }
843  // mark geometry of person plan parent deprecated and update geometry
844  personParent->markSegmentGeometryDeprecated();
845  personParent->updateGeometry();
846  }
847 }
848 
849 
850 void
851 GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
852  // first check that given vehicle isn't already a vehicle
853  if (originalVehicle->getTagProperty().getTag() != SUMO_TAG_VEHICLE) {
854  // get pointer to undo list (due originalVehicle will be deleted)
855  GNEUndoList* undoList = originalVehicle->getViewNet()->getUndoList();
856  // begin undo-redo operation
857  undoList->p_begin("transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
858  // declare flag to save if vehicle is selected
859  bool selected = originalVehicle->isAttributeCarrierSelected();
860  // first check if originalVehicle has an embedded route, and if true, separate it
861  if (((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) &&
862  (originalVehicle->getDemandElementParents().size() == 1)) {
863  originalVehicle = separateEmbeddedRoute(originalVehicle, undoList);
864  }
865  // obtain VType of original vehicle
866  GNEDemandElement* vType = originalVehicle->getDemandElementParents().at(0);
867  // extract vehicleParameters of originalVehicle
868  SUMOVehicleParameter newVehicleParameters = *originalVehicle;
869  // change tag in newVehicleParameters (needed for GNEVehicle constructor)
870  newVehicleParameters.tag = SUMO_TAG_VEHICLE;
871  // make transformation depending of vehicle tag
872  if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) {
873  // obtain vehicle's route (it always exist due call to function separateEmbeddedRoute(...)
874  GNEDemandElement* route = originalVehicle->getDemandElementParents().at(1);
875  // create Vehicle using values of original vehicle
876  GNEVehicle* vehicle = new GNEVehicle(originalVehicle->getViewNet(), vType, route, newVehicleParameters);
877  // remove original vehicle (to avoid problem with ID)
878  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
879  // add new vehicle
880  undoList->add(new GNEChange_DemandElement(vehicle, true), true);
881  // as last step change vehicle's route to embedded route if createEmbeddedRoute is enabled
882  if (createEmbeddedRoute) {
883  embebbeRoute(vehicle, undoList);
884  }
885  // check if vehicle has to be selected
886  if (selected) {
887  undoList->p_add(new GNEChange_Attribute(vehicle, vehicle->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
888  }
889  } else if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_FLOW) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_TRIP)) {
890  // create route using values of originalVehicle flow/trip
891  GNERoute* route = new GNERoute(originalVehicle->getViewNet(), RouteParameter(originalVehicle));
892  // create Vehicle using values of original vehicle (including ID)
893  GNEVehicle* vehicle = new GNEVehicle(originalVehicle->getViewNet(), vType, route, newVehicleParameters);
894  // remove flow/trip (to avoid problem with ID)
895  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
896  // add both new vehicle and route
897  undoList->add(new GNEChange_DemandElement(route, true), true);
898  undoList->add(new GNEChange_DemandElement(vehicle, true), true);
899  // check if vehicle has to be selected
900  if (selected) {
901  undoList->p_add(new GNEChange_Attribute(vehicle, vehicle->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
902  }
903  }
904  // end undo-redo operation
905  undoList->p_end();
906  }
907 }
908 
909 
910 void
911 GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
912  // first check that given vehicle isn't already a routeflow
913  if (originalVehicle->getTagProperty().getTag() != SUMO_TAG_ROUTEFLOW) {
914  // get pointer to undo list (due originalVehicle will be deleted)
915  GNEUndoList* undoList = originalVehicle->getViewNet()->getUndoList();
916  // begin undo-redo operation
917  undoList->p_begin("transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_ROUTEFLOW));
918  // declare flag to save if vehicle is selected
919  bool selected = originalVehicle->isAttributeCarrierSelected();
920  // first check if originalVehicle has an embedded route, and if true, separate it
921  if (((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) &&
922  (originalVehicle->getDemandElementParents().size() == 1)) {
923  originalVehicle = separateEmbeddedRoute(originalVehicle, undoList);
924  }
925  // obtain VType of original vehicle
926  GNEDemandElement* vType = originalVehicle->getDemandElementParents().at(0);
927  // extract vehicleParameters of originalVehicle
928  SUMOVehicleParameter newVehicleParameters = *originalVehicle;
929  // change tag in newVehicleParameters (needed for GNEVehicle constructor)
930  newVehicleParameters.tag = SUMO_TAG_ROUTEFLOW;
931  // make transformation depending of vehicle tag
932  if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) {
933  // obtain vehicle's route (it always exist due call to function separateEmbeddedRoute(...)
934  GNEDemandElement* route = originalVehicle->getDemandElementParents().at(1);
935  // create flow using newVehicleParameters
936  GNEVehicle* flow = new GNEVehicle(originalVehicle->getViewNet(), vType, route, newVehicleParameters);
937  // remove original vehicle (to avoid problem with ID)
938  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
939  // add new vehicle
940  undoList->add(new GNEChange_DemandElement(flow, true), true);
941  // as last step change vehicle's route to embedded route if createEmbeddedRoute is enabled
942  if (createEmbeddedRoute) {
943  embebbeRoute(flow, undoList);
944  }
945  // check if flow has to be selected
946  if (selected) {
947  undoList->p_add(new GNEChange_Attribute(flow, flow->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
948  }
949  } else if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_FLOW) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_TRIP)) {
950  // create route using values of originalVehicle flow/trip
951  GNERoute* route = new GNERoute(originalVehicle->getViewNet(), RouteParameter(originalVehicle));
952  // create flow using values of original vehicle (including ID)
953  GNEVehicle* flow = new GNEVehicle(originalVehicle->getViewNet(), vType, route, newVehicleParameters);
954  // remove flow/trip (to avoid problem with ID)
955  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
956  // add both new vehicle and route
957  undoList->add(new GNEChange_DemandElement(route, true), true);
958  undoList->add(new GNEChange_DemandElement(flow, true), true);
959  // check if flow has to be selected
960  if (selected) {
961  undoList->p_add(new GNEChange_Attribute(flow, flow->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
962  }
963  }
964  // end undo-redo operation
965  undoList->p_end();
966  }
967 }
968 
969 
970 void
972  // first check that given vehicle isn't already a trip
973  if (originalVehicle->getTagProperty().getTag() != SUMO_TAG_TRIP) {
974  // get pointer to undo list (due originalVehicle will be deleted)
975  GNEUndoList* undoList = originalVehicle->getViewNet()->getUndoList();
976  // begin undo-redo operation
977  undoList->p_begin("transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_FLOW));
978  // declare pointer to get embedded route if is created
979  GNEDemandElement* separatedEmbeddedRoute = nullptr;
980  // declare flag to save if vehicle is selected
981  bool selected = originalVehicle->isAttributeCarrierSelected();
982  // first check if originalVehicle has an embedded route, and if true, separate it
983  if (((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) &&
984  (originalVehicle->getDemandElementParents().size() == 1)) {
985  originalVehicle = separateEmbeddedRoute(originalVehicle, undoList);
986  }
987  // obtain VType of original vehicle
988  GNEDemandElement* vType = originalVehicle->getDemandElementParents().at(0);
989  // extract vehicleParameters of originalVehicle
990  SUMOVehicleParameter newVehicleParameters = *originalVehicle;
991  // change tag in newVehicleParameters (needed for GNEVehicle constructor)
992  newVehicleParameters.tag = SUMO_TAG_TRIP;
993  // make transformation depending of vehicle tag
994  if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) {
995  // create trip using values of original vehicle (including ID) and route's edges
996  GNEVehicle* trip = new GNEVehicle(originalVehicle->getViewNet(), vType,
997  originalVehicle->getDemandElementParents().at(1)->getEdgeParents().front(),
998  originalVehicle->getDemandElementParents().at(1)->getEdgeParents().back(),
999  newVehicleParameters);
1000  // first remove vehicle (to avoid problem with ID)
1001  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
1002  // add new vehicle
1003  undoList->add(new GNEChange_DemandElement(trip, true), true);
1004  // check if trip has to be selected
1005  if (selected) {
1006  undoList->p_add(new GNEChange_Attribute(trip, trip->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
1007  }
1008  } else if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_FLOW) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_TRIP)) {
1009  // create trip using values of original vehicle (including ID)
1010  GNEVehicle* trip = new GNEVehicle(originalVehicle->getViewNet(), vType, originalVehicle->getEdgeParents().front(), originalVehicle->getEdgeParents().back(), newVehicleParameters);
1011  // remove originalVehicle
1012  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
1013  // add new trip
1014  undoList->add(new GNEChange_DemandElement(trip, true), true);
1015  // check if trip has to be selected
1016  if (selected) {
1017  undoList->p_add(new GNEChange_Attribute(trip, trip->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
1018  }
1019  }
1020  // check if separatedEmbeddedRoute has to be removed
1021  if (separatedEmbeddedRoute) {
1022  undoList->add(new GNEChange_DemandElement(separatedEmbeddedRoute, false), true);
1023  }
1024  // end undo-redo operation
1025  undoList->p_end();
1026  }
1027 }
1028 
1029 
1030 void
1032  // first check that given vehicle isn't already a flow
1033  if (originalVehicle->getTagProperty().getTag() != SUMO_TAG_FLOW) {
1034  // get pointer to undo list (due originalVehicle will be deleted)
1035  GNEUndoList* undoList = originalVehicle->getViewNet()->getUndoList();
1036  // begin undo-redo operation
1037  undoList->p_begin("transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_FLOW));
1038  // declare pointer to get embedded route if is created
1039  GNEDemandElement* separatedEmbeddedRoute = nullptr;
1040  // declare flag to save if vehicle is selected
1041  bool selected = originalVehicle->isAttributeCarrierSelected();
1042  // first check if originalVehicle has an embedded route, and if true, separate it
1043  if (originalVehicle->getDemandElementParents().size() == 1) {
1044  originalVehicle = separateEmbeddedRoute(originalVehicle, undoList);
1045  separatedEmbeddedRoute = originalVehicle->getDemandElementParents().at(1);
1046  }
1047  // obtain VType of original vehicle
1048  GNEDemandElement* vType = originalVehicle->getDemandElementParents().at(0);
1049  // extract vehicleParameters of originalVehicle
1050  SUMOVehicleParameter newVehicleParameters = *originalVehicle;
1051  // change tag in newVehicleParameters (needed for GNEVehicle constructor)
1052  newVehicleParameters.tag = SUMO_TAG_FLOW;
1053  // make transformation depending of vehicle tag
1054  if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_ROUTEFLOW)) {
1055  // create Vehicle using values of original vehicle (including ID) and route's edges
1056  GNEVehicle* flow = new GNEVehicle(originalVehicle->getViewNet(), vType,
1057  originalVehicle->getDemandElementParents().at(1)->getEdgeParents().front(),
1058  originalVehicle->getDemandElementParents().at(1)->getEdgeParents().back(),
1059  newVehicleParameters);
1060  // first remove vehicle (to avoid problem with ID)
1061  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
1062  // add new flow
1063  undoList->add(new GNEChange_DemandElement(flow, true), true);
1064  } else if ((originalVehicle->getTagProperty().getTag() == SUMO_TAG_FLOW) || (originalVehicle->getTagProperty().getTag() == SUMO_TAG_TRIP)) {
1065  // create flow using values of original vehicle (including ID)
1066  GNEVehicle* flow = new GNEVehicle(originalVehicle->getViewNet(), vType, originalVehicle->getEdgeParents().front(), originalVehicle->getEdgeParents().back(), newVehicleParameters);
1067  // remove originalVehicle
1068  undoList->add(new GNEChange_DemandElement(originalVehicle, false), true);
1069  // add new flow
1070  undoList->add(new GNEChange_DemandElement(flow, true), true);
1071  // check if flow has to be selected
1072  if (selected) {
1073  undoList->p_add(new GNEChange_Attribute(flow, flow->getViewNet()->getNet(), GNE_ATTR_SELECTED, "true"));
1074  }
1075  }
1076  // check if separatedEmbeddedRoute has to be removed
1077  if (separatedEmbeddedRoute) {
1078  undoList->add(new GNEChange_DemandElement(separatedEmbeddedRoute, false), true);
1079  }
1080  // end undo-redo operation
1081  undoList->p_end();
1082  }
1083 }
1084 
1085 
1086 void
1088  //
1089 }
1090 
1091 
1092 void
1094  //
1095 }
1096 
1097 // ===========================================================================
1098 // protected
1099 // ===========================================================================
1100 
1101 void
1103  // create a copy of vehicle with the same attributes but without embedded route
1104  GNEVehicle* vehicleWithEmbebbeRoute = new GNEVehicle(vehicle->getViewNet(), vehicle->getDemandElementParents().at(0), *vehicle);
1105  // create a embeddedRoute based on parameters of vehicle's route
1106  GNERoute* embeddedRoute = new GNERoute(vehicleWithEmbebbeRoute->getViewNet(), vehicleWithEmbebbeRoute, RouteParameter(vehicle->getDemandElementParents().at(1)));
1107  // remove vehicle, but NOT route
1108  undoList->add(new GNEChange_DemandElement(vehicle, false), true);
1109  // now add bot vehicleWithEmbebbeRoute and embeddedRoute
1110  undoList->add(new GNEChange_DemandElement(vehicleWithEmbebbeRoute, true), true);
1111  undoList->add(new GNEChange_DemandElement(embeddedRoute, true), true);
1112 }
1113 
1114 
1115 GNEVehicle*
1117  // first create a Route based on the parameters of vehicle's embedded route
1118  GNERoute* nonEmbeddedRoute = new GNERoute(vehicle->getDemandElementChildren().at(0));
1119  // create a copy of vehicle with the same attributes but with the nonEmbeddedRoute
1120  GNEVehicle* vehicleWithoutEmbebbeRoute = new GNEVehicle(vehicle->getViewNet(), vehicle->getDemandElementParents().at(0), nonEmbeddedRoute, *vehicle);
1121  // remove embedded route andvehicle (because a embebbbed route without vehicle cannot exist)
1122  undoList->add(new GNEChange_DemandElement(vehicle->getDemandElementChildren().at(0), false), true);
1123  undoList->add(new GNEChange_DemandElement(vehicle, false), true);
1124  // now add bot nonEmbeddedRoute and vehicleWithoutEmbebbeRoute
1125  undoList->add(new GNEChange_DemandElement(nonEmbeddedRoute, true), true);
1126  undoList->add(new GNEChange_DemandElement(vehicleWithoutEmbebbeRoute, true), true);
1127  // return vehicleWithoutEmbebbeRoute
1128  return vehicleWithoutEmbebbeRoute;
1129 }
1130 
1131 
1132 void
1134  // currently unused
1135 }
1136 
1137 
1138 void
1140  // currently unused
1141 }
1142 
1143 
1144 void
1146  // change abort flag
1147  myAbort = false;
1148  // parse attribute of routes
1149  myRouteParameter.routeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ROUTE, SUMO_ATTR_ID, myAbort);
1150  myRouteParameter.setEdges(myViewNet, GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myRouteParameter.routeID, SUMO_TAG_ROUTE, SUMO_ATTR_EDGES, myAbort));
1151  myRouteParameter.color = GNEAttributeCarrier::parseAttributeFromXML<RGBColor>(attrs, myRouteParameter.routeID, SUMO_TAG_ROUTE, SUMO_ATTR_COLOR, myAbort);
1152 }
1153 
1154 
1155 void
1157  // change abort flag
1158  myAbort = false;
1159  // parse flow attributes
1161  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_FROM, myAbort),
1162  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_TO, myAbort),
1163  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_VIA, myAbort));
1164 }
1165 
1166 
1167 void
1169  // change abort flag
1170  myAbort = false;
1171  // parse trips attributes
1173  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_FROM, myAbort),
1174  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_TO, myAbort),
1175  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, myVehicleParameter->id, SUMO_TAG_TRIP, SUMO_ATTR_VIA, myAbort));
1176 }
1177 
1178 
1179 void
1180 GNERouteHandler::closeRoute(const bool /* mayBeDisconnected */) {
1181  // first copy generic parameters from SUMORouteHanlder to myRouteParameter
1183  // we have two possibilities: Either create a route with their own ID, or create a route within a vehicle
1184  if (myVehicleParameter) {
1185  if (myRouteParameter.edges.size() == 0) {
1186  WRITE_ERROR("A route needs at least one edge. Vehicle with ID='" + myVehicleParameter->id + "' cannot be created");
1187  } else {
1188  // obtain vType
1190  if (vType == nullptr) {
1191  WRITE_ERROR("Invalid vehicle type '" + myVehicleParameter->vtypeid + "' used in " + toString(myVehicleParameter->tag) + " '" + myVehicleParameter->id + "'.");
1192  } else {
1193  // generate a new route ID and add it to myVehicleParameter
1195  // due vehicle was loaded without a route, change tag
1197  // create vehicle or trips using myTemporalVehicleParameter without a route
1198  GNEVehicle* vehicleOrRouteFlow = new GNEVehicle(myViewNet, vType, *myVehicleParameter);
1199  // creaste embedded route
1200  GNERoute* embeddedRoute = new GNERoute(myViewNet, vehicleOrRouteFlow, myRouteParameter);
1201  // add both to net depending of myUndoDemandElements
1202  if (myUndoDemandElements) {
1203  myViewNet->getUndoList()->p_begin("add vehicle and " + embeddedRoute->getTagStr());
1204  // add both in net using undoList
1205  myViewNet->getUndoList()->add(new GNEChange_DemandElement(vehicleOrRouteFlow, true), true);
1206  myViewNet->getUndoList()->add(new GNEChange_DemandElement(embeddedRoute, true), true);
1207  // iterate over stops of myActiveRouteStops and create stops associated with it
1208  for (const auto& i : myActiveRouteStops) {
1209  buildStop(myViewNet, true, i, vehicleOrRouteFlow, false);
1210  }
1211  myViewNet->getUndoList()->p_end();
1212  } else {
1213  // add vehicleOrRouteFlow in net and in their vehicle type parent
1214  myViewNet->getNet()->insertDemandElement(vehicleOrRouteFlow);
1215  vType->addDemandElementChild(vehicleOrRouteFlow);
1216  vehicleOrRouteFlow->incRef("buildVehicleAndRoute");
1217  // add route manually in net, and in all of their edges and in vehicleOrRouteFlow
1218  myViewNet->getNet()->insertDemandElement(embeddedRoute);
1219  for (const auto& i : myRouteParameter.edges) {
1220  i->addDemandElementChild(vehicleOrRouteFlow);
1221  }
1222  vehicleOrRouteFlow->addDemandElementChild(embeddedRoute);
1223  embeddedRoute->incRef("buildVehicleAndRoute");
1224  // iterate over stops of myActiveRouteStops and create stops associated with it
1225  for (const auto& i : myActiveRouteStops) {
1226  buildStop(myViewNet, false, i, vehicleOrRouteFlow, false);
1227  }
1228  }
1229  }
1230  }
1231  // delete myVehicleParameter because at the end of this function closeVehicle()/closeFlow() will be called
1232  delete myVehicleParameter;
1233  myVehicleParameter = nullptr;
1235  WRITE_ERROR(toString(SUMO_TAG_ROUTE) + " ID='" + myRouteParameter.routeID + "' contains invalid characters.");
1236  } else if (myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_ROUTE, myRouteParameter.routeID, false) != nullptr) {
1237  WRITE_ERROR("There is another " + toString(SUMO_TAG_ROUTE) + " with the same ID='" + myRouteParameter.routeID + "'.");
1238  } else if (myRouteParameter.edges.size() == 0) {
1239  WRITE_ERROR("A route needs at least one edge.");
1240  } else {
1241  // creaste GNERoute
1243  if (myUndoDemandElements) {
1244  myViewNet->getUndoList()->p_begin("add " + route->getTagStr());
1245  myViewNet->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
1246  // iterate over stops of myActiveRouteStops and create stops associated with it
1247  for (const auto& i : myActiveRouteStops) {
1248  buildStop(myViewNet, true, i, route, false);
1249  }
1250  myViewNet->getUndoList()->p_end();
1251  } else {
1253  for (const auto& i : myRouteParameter.edges) {
1254  i->addDemandElementChild(route);
1255  }
1256  route->incRef("buildRoute");
1257  // iterate over stops of myActiveRouteStops and create stops associated with it
1258  for (const auto& i : myActiveRouteStops) {
1259  buildStop(myViewNet, false, i, route, false);
1260  }
1261  }
1262  }
1263 }
1264 
1265 
1266 void
1268  // currently unused
1269 }
1270 
1271 
1272 void
1274  // currently unused
1275 }
1276 
1277 
1278 void
1280  // first check if myVehicleParameter was sucesfully created
1281  if (myVehicleParameter) {
1282  // build vehicle over route
1284  }
1285 }
1286 
1287 
1288 void
1290  // first check that VType was sucesfully created
1291  if (myCurrentVType) {
1292  // first check if loaded VType is a default vtype
1294  // overwrite default vehicle type
1296  } else if (myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_VTYPE, myCurrentVType->id, false) != nullptr) {
1297  WRITE_ERROR("There is another " + toString(SUMO_TAG_VTYPE) + " with the same ID='" + myCurrentVType->id + "'.");
1298  } else {
1299  // check if we're creating a vType or a pType
1301  // create VType using myCurrentVType
1302  GNEVehicleType* vType = new GNEVehicleType(myViewNet, *myCurrentVType, vTypeTag);
1303  if (myUndoDemandElements) {
1304  myViewNet->getUndoList()->p_begin("add " + vType->getTagStr());
1305  myViewNet->getUndoList()->add(new GNEChange_DemandElement(vType, true), true);
1306  myViewNet->getUndoList()->p_end();
1307  } else {
1309  vType->incRef("buildVType");
1310  }
1311  }
1312  }
1313 }
1314 
1315 
1316 void
1318  // first check if myVehicleParameter was sucesfully created
1319  if (myVehicleParameter) {
1320  // first check if ID is duplicated
1322  // obtain ptype
1324  if (pType == nullptr) {
1325  WRITE_ERROR("Invalid person type '" + myVehicleParameter->vtypeid + "' used in " + toString(myVehicleParameter->tag) + " '" + myVehicleParameter->vtypeid + "'.");
1326  } else {
1327  // declare flag to abort person plans creation
1328  bool abortPersonPlans = false;
1329  // create person using personParameters
1331  // begin undo-list creation
1332  myViewNet->getUndoList()->p_begin("add " + person->getTagStr());
1333  // add person
1334  myViewNet->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
1335  // iterate over all personplan childs and add it
1336  for (auto i = myPersonPlanValues.begin(); (i != myPersonPlanValues.end()) && !abortPersonPlans; i++) {
1337  switch (i->tag) {
1339  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1340  if (i->from) {
1341  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEPersonTrip(myViewNet, person, i->calculateEdgePath(), i->vTypes, i->modes, i->arrivalPos), true), true);
1342  } else if (i != myPersonPlanValues.begin()) {
1343  // update 'from' edge using 'to' edge of last personPlan element
1344  i->from = (i - 1)->getLastEdge();
1345  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEPersonTrip(myViewNet, person, i->calculateEdgePath(), i->vTypes, i->modes, i->arrivalPos), true), true);
1346  } else {
1347  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1348  // abort last command group (to remove created person)
1350  // abort person plan creation
1351  abortPersonPlans = true;
1352  }
1353  break;
1355  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1356  if (i->from) {
1357  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEPersonTrip(myViewNet, person, i->calculateEdgePath(), i->busStop, i->vTypes, i->modes), true), true);
1358  } else if (i != myPersonPlanValues.begin()) {
1359  // update 'from' edge using 'to' edge of last personPlan element
1360  i->from = (i - 1)->getLastEdge();
1361  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEPersonTrip(myViewNet, person, i->calculateEdgePath(), i->busStop, i->vTypes, i->modes), true), true);
1362  } else {
1363  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1364  // abort last command group (to remove created person)
1366  // abort person plan creation
1367  abortPersonPlans = true;
1368  }
1369  break;
1370  case SUMO_TAG_RIDE_FROMTO:
1371  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1372  if (i->from) {
1373  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNERide(myViewNet, person, i->calculateEdgePath(), i->arrivalPos, i->lines), true), true);
1374  } else if (i != myPersonPlanValues.begin()) {
1375  // update 'from' edge using 'to' edge of last personPlan element
1376  i->from = (i - 1)->getLastEdge();
1377  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNERide(myViewNet, person, i->calculateEdgePath(), i->arrivalPos, i->lines), true), true);
1378  } else {
1379  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1380  // abort last command group (to remove created person)
1382  // abort person plan creation
1383  abortPersonPlans = true;
1384  }
1385  break;
1386  case SUMO_TAG_RIDE_BUSSTOP:
1387  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1388  if (i->from) {
1389  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNERide(myViewNet, person, i->calculateEdgePath(), i->busStop, i->lines), true), true);
1390  } else if (i != myPersonPlanValues.begin()) {
1391  // update 'from' edge using 'to' edge of last personPlan element
1392  i->from = (i - 1)->getLastEdge();
1393  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNERide(myViewNet, person, i->calculateEdgePath(), i->busStop, i->lines), true), true);
1394  } else {
1395  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1396  // abort last command group (to remove created person)
1398  // abort person plan creation
1399  abortPersonPlans = true;
1400  }
1401  break;
1402  case SUMO_TAG_WALK_EDGES:
1403  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, SUMO_TAG_WALK_EDGES, i->edges, i->arrivalPos), true), true);
1404  break;
1405  case SUMO_TAG_WALK_FROMTO:
1406  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1407  if (i->from) {
1408  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, SUMO_TAG_WALK_FROMTO, i->calculateEdgePath(), i->arrivalPos), true), true);
1409  } else if (i != myPersonPlanValues.begin()) {
1410  // update 'from' edge using 'to' edge of last personPlan element
1411  i->from = (i - 1)->getLastEdge();
1412  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, SUMO_TAG_WALK_FROMTO, i->calculateEdgePath(), i->arrivalPos), true), true);
1413  } else {
1414  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1415  // abort last command group (to remove created person)
1417  // abort person plan creation
1418  abortPersonPlans = true;
1419  }
1420  break;
1421  case SUMO_TAG_WALK_BUSSTOP:
1422  // check if "from" attribute was loaded, or it must be taked fron previous personPlan values
1423  if (i->from) {
1424  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, i->calculateEdgePath(), i->busStop), true), true);
1425  } else if (i != myPersonPlanValues.begin()) {
1426  // update 'from' edge using 'to' edge of last personPlan element
1427  i->from = (i - 1)->getLastEdge();
1428  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, i->calculateEdgePath(), i->busStop), true), true);
1429  } else {
1430  WRITE_ERROR("The first person plan of type '" + toString(i->tag) + "' needs a from edge. Person cannot be created.");
1431  // abort last command group (to remove created person)
1433  // abort person plan creation
1434  abortPersonPlans = true;
1435  }
1436  break;
1437  case SUMO_TAG_WALK_ROUTE:
1438  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEWalk(myViewNet, person, i->route, i->arrivalPos), true), true);
1439  break;
1441  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEStop(myViewNet, i->stopParameters, i->laneStop, i->friendlyPos, person), true), true);
1442  break;
1444  myViewNet->getUndoList()->add(new GNEChange_DemandElement(new GNEStop(i->tag, myViewNet, i->stopParameters, i->busStop, person), true), true);
1445  break;
1446  default:
1447  break;
1448  }
1449  }
1450  // end undo-list depending of abortPersonPlans
1451  if (!abortPersonPlans) {
1452  myViewNet->getUndoList()->p_end();
1453  }
1454  }
1455  }
1456 
1457  }
1458  // clear person plan values clear
1459  myPersonPlanValues.clear();
1460 }
1461 
1462 void
1464  // first check if myVehicleParameter was sucesfully created
1465  if (myVehicleParameter) {
1466  // build person flow
1468  }
1469 }
1470 
1471 void
1473  // currently unused
1474 }
1475 
1476 
1477 void
1479  // first check if myVehicleParameter was sucesfully created
1480  if (myVehicleParameter) {
1481  // check if we're creating a flow or a routeFlow over route
1482  if (myRouteParameter.edges.size() > 0) {
1483  // build flow
1485  } else {
1486  // build flow over route
1488  }
1489  }
1490 }
1491 
1492 
1493 void
1495  // first check if myVehicleParameter was sucesfully created
1496  if (myVehicleParameter && (myRouteParameter.edges.size() > 0)) {
1497  // force reroute
1499  // build trip
1501  }
1502 }
1503 
1504 
1505 void
1507  // declare a personStop
1508  PersonPlansValues stop;
1509  std::string errorSuffix;
1510  if (myVehicleParameter != nullptr) {
1511  errorSuffix = " in " + toString(myVehicleParameter->tag) + " '" + myVehicleParameter->id + "'.";
1512  } else {
1513  errorSuffix = " in route '" + myActiveRouteID + "'.";
1514  }
1515  // try to parse stop
1516  myAbort = parseStop(stop.stopParameters, attrs, errorSuffix, MsgHandler::getErrorInstance());
1517  if (!myAbort) {
1518  return;
1519  }
1520  // try to parse the assigned bus stop
1521  if (stop.stopParameters.busstop != "") {
1522  // ok, we have a bus stop
1524  if (bs == nullptr) {
1525  WRITE_ERROR("The busStop '" + stop.stopParameters.busstop + "' is not known" + errorSuffix);
1526  return;
1527  }
1528  // save lane
1530  // save stoping place in stop
1531  stop.busStop = bs;
1532  // set tag
1533  stop.tag = SUMO_TAG_STOP_BUSSTOP;
1534  // special case for persons
1537  }
1538  } else {
1539  // no, the lane and the position should be given
1540  // get the lane
1541  stop.stopParameters.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, myAbort, "");
1542  stop.laneStop = myViewNet->getNet()->retrieveLane(stop.stopParameters.lane, false);
1543  // check if lane is valid
1544  if (myAbort && stop.stopParameters.lane != "") {
1545  if (stop.laneStop == nullptr) {
1546  WRITE_ERROR("The lane '" + stop.stopParameters.lane + "' for a stop is not known" + errorSuffix);
1547  return;
1548  }
1549  } else {
1550  WRITE_ERROR("A stop must be placed on a busStop, a chargingStation, a containerStop a parkingArea or a lane" + errorSuffix);
1551  return;
1552  }
1553  // calculate start and end position
1554  stop.stopParameters.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, myAbort, stop.laneStop->getLaneParametricLength());
1555  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
1556  WRITE_ERROR("Deprecated attribute 'pos' in description of stop" + errorSuffix);
1557  stop.stopParameters.endPos = attrs.getOpt<double>(SUMO_ATTR_POSITION, nullptr, myAbort, stop.stopParameters.endPos);
1558  }
1559  stop.stopParameters.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, myAbort, MAX2(0., stop.stopParameters.endPos - 2 * POSITION_EPS));
1560  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, myAbort, false);
1561  if (!myAbort || !checkStopPos(stop.stopParameters.startPos, stop.stopParameters.endPos, stop.laneStop->getLaneParametricLength(), POSITION_EPS, friendlyPos)) {
1562  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.stopParameters.lane + "'" + errorSuffix);
1563  return;
1564  }
1565  // set tag
1566  stop.tag = SUMO_TAG_STOP_LANE;
1567  // special case for persons
1570  }
1571  }
1572  if (myVehicleParameter != nullptr) {
1574  myPersonPlanValues.push_back(stop);
1575  } else {
1576  myVehicleParameter->stops.push_back(stop.stopParameters);
1577  }
1578  } else {
1579  myActiveRouteStops.push_back(stop.stopParameters);
1580  }
1581 }
1582 
1583 
1584 void
1586  // SUMORouteHandler handle certain walks configurations as PersonTrips, then it needs a manually call to addWalk(...)
1587  if (attrs.getObjectType() == "walk") {
1588  addWalk(attrs);
1589  } else {
1590  // change abort flag
1591  myAbort = false;
1592  // declare value for saving loaded values
1593  PersonPlansValues personTripValuesLoaded;
1594  // first set tag
1595  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
1596  // set tag
1597  personTripValuesLoaded.tag = SUMO_TAG_PERSONTRIP_FROMTO;
1598  // declare a flag to check if values are valid
1599  bool validValues = true;
1600  // extract rest of parameters
1601  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1602  personTripValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1603  if (personTripValuesLoaded.from == nullptr) {
1604  WRITE_ERROR("Invalid edge from in " + toString(personTripValuesLoaded.tag));
1605  validValues = false;
1606  }
1607  }
1608  personTripValuesLoaded.to = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_TO, myAbort), false);
1609  personTripValuesLoaded.vTypes = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_VTYPES, myAbort);
1610  personTripValuesLoaded.modes = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_MODES, myAbort);
1611  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1612  personTripValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1613  }
1614  // check that all parameters are correct
1615  if (personTripValuesLoaded.to == nullptr) {
1616  WRITE_ERROR("Invalid edge to in " + toString(personTripValuesLoaded.tag));
1617  validValues = false;
1618  }
1619  // check modes
1620  for (const auto& i : personTripValuesLoaded.modes) {
1621  if ((i != "public") && (i != "car") && (i != "bicycle")) {
1622  validValues = false;
1623  }
1624  }
1625  if (validValues) {
1626  // remove duplicated modes
1627  std::sort(personTripValuesLoaded.modes.begin(), personTripValuesLoaded.modes.end());
1628  personTripValuesLoaded.modes.erase(unique(personTripValuesLoaded.modes.begin(), personTripValuesLoaded.modes.end()), personTripValuesLoaded.modes.end());
1629  } else {
1630  WRITE_ERROR("A person trip mode can be only a combination of 'public', 'car' or 'bicycle'");
1631  }
1632  for (const auto& i : personTripValuesLoaded.vTypes) {
1634  WRITE_ERROR("Invalid vehicle type '" + i + "' used in " + toString(personTripValuesLoaded.tag));
1635  validValues = false;
1636  }
1637  }
1638  // save loaded values in container only if all parameters are valid
1639  if (validValues) {
1640  myPersonPlanValues.push_back(personTripValuesLoaded);
1641  }
1642  } else if (attrs.hasAttribute(SUMO_ATTR_BUS_STOP)) {
1643  // set tag
1644  personTripValuesLoaded.tag = SUMO_TAG_PERSONTRIP_BUSSTOP;
1645  // declare a flag to check if values are valid
1646  bool validValues = true;
1647  // extract rest of parameters
1648  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1649  personTripValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1650  if (personTripValuesLoaded.from == nullptr) {
1651  WRITE_ERROR("Invalid edge from in " + toString(personTripValuesLoaded.tag));
1652  validValues = false;
1653  }
1654  }
1655  personTripValuesLoaded.busStop = myViewNet->getNet()->retrieveAdditional(SUMO_TAG_BUS_STOP, GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_BUS_STOP, myAbort), false);
1656  personTripValuesLoaded.vTypes = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_VTYPES, myAbort);
1657  personTripValuesLoaded.modes = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_MODES, myAbort);
1658  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1659  personTripValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", personTripValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1660  }
1661  // check that all parameters are correct
1662  if (personTripValuesLoaded.busStop == nullptr) {
1663  WRITE_ERROR("Invalid busStop to in " + toString(personTripValuesLoaded.tag));
1664  validValues = false;
1665  }
1666  // check modes
1667  for (const auto& i : personTripValuesLoaded.modes) {
1668  if ((i != "public") && (i != "car") && (i != "bicycle")) {
1669  validValues = false;
1670  }
1671  }
1672  if (validValues) {
1673  // remove duplicated modes
1674  std::sort(personTripValuesLoaded.modes.begin(), personTripValuesLoaded.modes.end());
1675  personTripValuesLoaded.modes.erase(unique(personTripValuesLoaded.modes.begin(), personTripValuesLoaded.modes.end()), personTripValuesLoaded.modes.end());
1676  } else {
1677  WRITE_ERROR("A person trip mode can be only a combination of 'public', 'car' or 'bicycle'");
1678  }
1679  for (const auto& i : personTripValuesLoaded.vTypes) {
1681  WRITE_ERROR("Invalid vehicle type '" + i + "' used in " + toString(personTripValuesLoaded.tag));
1682  validValues = false;
1683  }
1684  }
1685  // save loaded values in container only if all parameters are valid
1686  if (validValues) {
1687  myPersonPlanValues.push_back(personTripValuesLoaded);
1688  }
1689  } else {
1690  WRITE_ERROR("A personTrip requieres either a from-to edges or a from edge and a busStop");
1691  }
1692  }
1693 }
1694 
1695 
1696 void
1698  // change abort flag
1699  myAbort = false;
1700  // declare value for saving loaded values
1701  PersonPlansValues walkValuesLoaded;
1702  // first set tag
1703  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
1704  // set tag
1705  walkValuesLoaded.tag = SUMO_TAG_WALK_EDGES;
1706  // parse edges
1707  std::string edgeIDs = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_EDGES, myAbort);
1708  if (GNEAttributeCarrier::canParse<std::vector<GNEEdge*> >(myViewNet->getNet(), edgeIDs, true)) {
1709  walkValuesLoaded.edges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(myViewNet->getNet(), edgeIDs);
1710  }
1711  // extract rest of parameters
1712  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1713  walkValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1714  }
1715  // check that all parameters are correct
1716  if (walkValuesLoaded.edges.empty()) {
1717  WRITE_ERROR("Invalid edges of " + toString(walkValuesLoaded.tag));
1718  } else {
1719  // save loaded values in container
1720  myPersonPlanValues.push_back(walkValuesLoaded);
1721  }
1722  } else if (attrs.hasAttribute(SUMO_ATTR_TO)) {
1723  // set tag
1724  walkValuesLoaded.tag = SUMO_TAG_WALK_FROMTO;
1725  // extract rest of parameters
1726  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1727  walkValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1728  if (walkValuesLoaded.from == nullptr) {
1729  WRITE_ERROR("Invalid edge from in " + toString(walkValuesLoaded.tag));
1730  }
1731  }
1732  walkValuesLoaded.to = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_TO, myAbort), false);
1733  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1734  walkValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1735  }
1736  // check that all parameters are correct
1737  if (walkValuesLoaded.to == nullptr) {
1738  WRITE_ERROR("Invalid edge to in " + toString(walkValuesLoaded.tag));
1739  } else {
1740  // save loaded values in container
1741  myPersonPlanValues.push_back(walkValuesLoaded);
1742  }
1743  } else if (attrs.hasAttribute(SUMO_ATTR_BUS_STOP)) {
1744  // set tag
1745  walkValuesLoaded.tag = SUMO_TAG_WALK_BUSSTOP;
1746  // extract rest of parameters
1747  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1748  walkValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1749  if (walkValuesLoaded.from == nullptr) {
1750  WRITE_ERROR("Invalid edge from in " + toString(walkValuesLoaded.tag));
1751  }
1752  }
1753  walkValuesLoaded.busStop = myViewNet->getNet()->retrieveAdditional(SUMO_TAG_BUS_STOP, GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_BUS_STOP, myAbort), false);
1754  // use edge of busstop's lane as to edge
1755  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1756  walkValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1757  }
1758  // check that all parameters are correct
1759  if (walkValuesLoaded.busStop == nullptr) {
1760  WRITE_ERROR("Invalid busStop to in " + toString(walkValuesLoaded.tag));
1761  } else {
1762  // save loaded values in container
1763  myPersonPlanValues.push_back(walkValuesLoaded);
1764  }
1765  } else if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
1766  // set tag
1767  walkValuesLoaded.tag = SUMO_TAG_WALK_ROUTE;
1768  // extract rest of parameters
1769  walkValuesLoaded.route = myViewNet->getNet()->retrieveDemandElement(SUMO_TAG_ROUTE, GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_ROUTE, myAbort), false);
1770  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1771  walkValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", walkValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1772  }
1773  // check that all parameters are correct
1774  if (walkValuesLoaded.route == nullptr) {
1775  WRITE_ERROR("Invalid route from in " + toString(walkValuesLoaded.tag));
1776  } else {
1777  // save loaded values in container
1778  myPersonPlanValues.push_back(walkValuesLoaded);
1779  }
1780  } else {
1781  WRITE_ERROR("A walk requieres either a from-to edges, a from edge and a busStop or a route");
1782  }
1783 }
1784 
1785 
1786 void
1788  // currently unused
1789 }
1790 
1791 
1792 void
1794  // currently unused
1795 }
1796 
1797 
1798 void
1800  // change abort flag
1801  myAbort = false;
1802  // declare value for saving loaded values
1803  PersonPlansValues rideValuesLoaded;
1804  // first set tag
1805  if (attrs.hasAttribute(SUMO_ATTR_TO)) {
1806  // set tag
1807  rideValuesLoaded.tag = SUMO_TAG_RIDE_FROMTO;
1808  // extract rest of parameters
1809  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1810  rideValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1811  if (rideValuesLoaded.from == nullptr) {
1812  WRITE_ERROR("Invalid edge from in " + toString(rideValuesLoaded.tag));
1813  }
1814  }
1815  rideValuesLoaded.to = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_TO, myAbort), false);
1816  rideValuesLoaded.lines = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_LINES, myAbort);
1817  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1818  rideValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1819  }
1820  // check lines
1821  if (rideValuesLoaded.lines.empty()) {
1822  rideValuesLoaded.lines.push_back("ANY");
1823  }
1824  // check that all parameters are correct
1825  if (rideValuesLoaded.to == nullptr) {
1826  WRITE_ERROR("Invalid edge to in " + toString(rideValuesLoaded.tag));
1827  } else {
1828  // save loaded values in container
1829  myPersonPlanValues.push_back(rideValuesLoaded);
1830  }
1831  } else if (attrs.hasAttribute(SUMO_ATTR_BUS_STOP)) {
1832  // set tag
1833  rideValuesLoaded.tag = SUMO_TAG_RIDE_BUSSTOP;
1834  // extract rest of parameters
1835  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
1836  rideValuesLoaded.from = myViewNet->getNet()->retrieveEdge(GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_FROM, myAbort), false);
1837  if (rideValuesLoaded.from == nullptr) {
1838  WRITE_ERROR("Invalid edge from in " + toString(rideValuesLoaded.tag));
1839  }
1840  }
1841  rideValuesLoaded.busStop = myViewNet->getNet()->retrieveAdditional(SUMO_TAG_BUS_STOP, GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_BUS_STOP, myAbort), false);
1842  rideValuesLoaded.lines = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_LINES, myAbort);
1843  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1844  rideValuesLoaded.arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", rideValuesLoaded.tag, SUMO_ATTR_ARRIVALPOS, myAbort);
1845  }
1846  // check lines
1847  if (rideValuesLoaded.lines.empty()) {
1848  rideValuesLoaded.lines.push_back("ANY");
1849  }
1850  // check that all parameters are correct
1851  if (rideValuesLoaded.busStop == nullptr) {
1852  WRITE_ERROR("Invalid busStop to in " + toString(rideValuesLoaded.tag));
1853  } else {
1854  // save loaded values in container
1855  myPersonPlanValues.push_back(rideValuesLoaded);
1856  }
1857  } else {
1858  WRITE_ERROR("A ride requieres either a from-to edges or a from edge and a busStop");
1859  }
1860 }
1861 
1862 
1863 void
1865  // currently unused
1866 }
1867 
1868 
1869 void
1871  // currently unused
1872 }
1873 
1874 // ===========================================================================
1875 // private members
1876 // ===========================================================================
1877 
1879  tag(SUMO_TAG_NOTHING),
1880  from(nullptr),
1881  to(nullptr),
1882  busStop(nullptr),
1883  route(nullptr),
1884  arrivalPos(-1),
1885  laneStop(nullptr),
1886  friendlyPos(false) {
1887 }
1888 
1889 
1890 GNEEdge*
1892  if (edges.size() > 0) {
1893  return edges.back();
1894  } else if (route) {
1895  return route->getEdgeParents().back();
1896  } else if (busStop) {
1897  return &busStop->getLaneParents().front()->getParentEdge();
1898  } else if (laneStop) {
1899  return &laneStop->getParentEdge();
1900  } else if (to) {
1901  return to;
1902  } else {
1903  return nullptr;
1904  }
1905 }
1906 
1907 
1908 std::vector<GNEEdge*>
1910  // first check that from and to exist and are differents
1911  if ((from && to) && (from != to)) {
1912  // calculate edge path between from and to eges
1914  if (edgePath.empty()) {
1915  return {from, to};
1916  } else {
1917  return edgePath;
1918  }
1919  } else if (from && busStop) {
1920  // calculate edge path between from and busstop's lane
1921  std::vector<GNEEdge*> edgePath = GNEDemandElement::getRouteCalculatorInstance()->calculateDijkstraRoute(SVC_PEDESTRIAN, {from, &busStop->getLaneParents().front()->getParentEdge()});
1922  if (edgePath.empty()) {
1923  return {from, &busStop->getLaneParents().front()->getParentEdge()};
1924  } else {
1925  return edgePath;
1926  }
1927  } else if (from) {
1928  return {from};
1929  } else if (to) {
1930  return {to};
1931  } else {
1932  throw InvalidArgument("At least from or to edge must be valid");
1933  }
1934 }
1935 
1936 /****************************************************************************/
stop placed over a parking area (used in netedit)
void closeRouteDistribution()
closes (ends) the building of a distribution
RouteParameter myRouteParameter
NETEDIT Route Parameters.
void closeVehicle()
Ends the processing of a vehicle.
void closeFlow()
Ends the processing of a routeFlow.
SUMOVehicleClass VClass
VClass used by this route.
std::vector< GNEEdge * > calculateDijkstraRoute(SUMOVehicleClass vClass, const std::vector< GNEEdge *> &partialEdges) const
calculate Dijkstra route between a list of partial edges
SumoXMLTag
Numbers representing SUMO-XML - element names.
bool myAbort
flag used for parsing values
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:81
static void transformToVehicle(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform vehicle functions
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:1020
std::string lane
The lane to stop at.
const int VEHPARS_FORCE_REROUTE
description of a vehicle type
~GNERouteHandler()
Destructor.
std::vector< GNEEdge * > calculateEdgePath() const
calculate ege path between from-to edges
struct for saving route parameters
std::string vtypeid
The vehicle&#39;s type id.
a flow definitio nusing a from-to edges instead of a route (used by router)
static void buildRideFromTo(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, const std::vector< std::string > &lines, double arrivalPos)
build ride using a from-to edges
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, container or flow.
static bool isPersonIdDuplicated(GNEViewNet *viewNet, const std::string &id)
check if there is already a person (Person or PersonFlow) with the given ID
static void buildTrip(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &vehicleParameters, const std::vector< GNEEdge *> &edges)
build trip
GNEAdditional * busStop
busStop
a flow definition nusing a route instead of a from-to edges route (used in NETEDIT) ...
std::vector< std::string > modes
modes
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
void setEdges(GNEViewNet *viewNet, const std::string &edgeIDs)
set edges (list of consecutive edges)
static void overwriteVType(GNEDemandElement *vType, SUMOVTypeParameter *newVTypeParameter, GNEUndoList *undoList)
overwrite all values of GNEVehicleType with a SUMOVTypeParameter
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
opens a type distribution for reading
static void transformToTrip(GNEVehicle *originalVehicle)
transform to trip
virtual void updateGeometry()=0
update pre-computed geometry information
int parametersSet
Information for the router which parameter were set, TraCI may modify this (whe changing color) ...
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
RGBColor color
string for saving parsed route colors
static void embebbeRoute(GNEVehicle *vehicle, GNEUndoList *undoList)
embebbe route within a vehicle
void openTrip(const SUMOSAXAttributes &attrs)
opens a trip for reading
stop placed over a lane (used in netedit)
SUMOVehicleClass vehicleClass
The vehicle&#39;s class.
void closeContainer()
Ends the processing of a container.
std::string busstop
(Optional) bus stop if one is assigned to the stop
SUMOVehicleParameter::Stop stopParameters
stop parameters
T MAX2(T a, T b)
Definition: StdDefs.h:80
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:73
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
virtual double getAttributeDouble(SumoXMLAttr key) const =0
const std::string & getObjectType() const
return the objecttype to which these attributes belong
std::vector< std::string > lines
lines
const std::string DEFAULT_BIKETYPE_ID
static bool isVehicleIdDuplicated(GNEViewNet *viewNet, const std::string &id)
check if there is already a vehicle (Vehicle, Trip, Flow or Flow) with the given ID ...
std::string myActiveRouteID
The id of the current route.
struct used for load person plans (Rides, Walks, etc.)
static void buildFlow(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &vehicleParameters, const std::vector< GNEEdge *> &edges)
build flow
std::string parkingarea
(Optional) parking area if one is assigned to the stop
Parameterised genericParameters
generic parameters
const std::string DEFAULT_VTYPE_ID
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
static RouteCalculator * getRouteCalculatorInstance()
obtain instance of RouteCalculator
begin/end of the description of a route
static void buildRideBusStop(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, GNEAdditional *busStop, const std::vector< std::string > &lines)
build ride using a from edge and a busStop
The speed is given.
void addRide(const SUMOSAXAttributes &attrs)
Processing of a ride.
const std::vector< GNEEdge * > & getEdgeParents() const
get edge parents
The lane is given.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
const std::vector< GNEDemandElement * > & getDemandElementChildren() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
static void transformToFlow(GNEVehicle *originalVehicle)
transform to flow
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2133
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
void closePersonFlow()
Ends the processing of a personFlow.
double departSpeed
(optional) The initial speed of the vehicle
the function-object for an editing operation (abstract base)
std::vector< GNEEdge * > edges
edges
void openFlow(const SUMOSAXAttributes &attrs)
opens a routeFlow for reading
GNEUndoList * getUndoList() const
get the undoList object
Definition: GNEViewNet.cpp:933
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition: GNELane.cpp:751
virtual SUMOVehicleClass getVClass() const =0
obtain VClass related with this demand element
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
stop placed over a charging station (used in netedit)
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
std::vector< GNEEdge * > edges
list of edges
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1292
std::string routeid
The vehicle&#39;s route id.
Encapsulated SAX-Attributes.
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2266
const int VEHPARS_DEPARTSPEED_SET
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:80
void addTranship(const SUMOSAXAttributes &attrs)
Processing of a tranship.
void markSegmentGeometryDeprecated()
mark demand element segment geometry as deprecated
GNEEdge * getLastEdge() const
return last valid edge (used to create consecutive person plans)
bool isPerson() const
return true if tag correspond to a person element
const std::vector< GNELane * > & getLaneParents() const
get lanes of VSS
stop placed over a containerStop (used in netedit)
stop placed over a busStop (used in netedit)
static void buildPerson(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &personParameters)
build person
void closePerson()
Ends the processing of a person.
void openRoute(const SUMOSAXAttributes &attrs)
opens a route for reading
A lane area vehicles can halt at (netedit-version)
Definition: GNEBusStop.h:35
#define POSITION_EPS
Definition: config.h:169
GNEViewNet * myViewNet
pointer to View&#39;s Net
bool myUndoDemandElements
flag to check if created demand elements must be undo and redo
const std::string getID() const
function to support debugging
static void buildWalkFromTo(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, double arrivalPos)
build walk using a from-to edges
void closeRoute(const bool mayBeDisconnected=false)
double endPos
The stopping position end.
static void buildPersonFlow(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &personFlowParameters)
build person flow
void incRef(const std::string &debugMsg="")
Increarse reference.
std::string generateDemandElementID(const std::string &prefix, SumoXMLTag type) const
generate demand element id
Definition: GNENet.cpp:2411
void p_abortLastCommandGroup()
reverts last command group
vehicle is a passenger car (a "normal" car)
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double arrivalPos
(optional) The position the vehicle shall arrive on
Definition of vehicle stop (position and duration)
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
Parser for routes during their loading.
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
std::vector< std::string > via
List of the via-edges the vehicle must visit.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:50
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
void addDemandElementChild(GNEDemandElement *demandElement)
const std::vector< GNEDemandElement * > & getDemandElementParents() const
return vector of demand elements that have as Parent this edge (For example, Calibrators) ...
static void transformToPersonFlow(GNEPerson *originalPerson)
transform routeFlow over an existent route
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
double startPos
The stopping position start.
static bool checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
Structure representing possible vehicle parameter.
static void transformToRouteFlow(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform routeFlow over an existent route
void addPerson(const SUMOSAXAttributes &attrs)
Processing of a person.
static void buildWalkRoute(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, GNEDemandElement *routeParent, double arrivalPos)
build walk using a list of consecutive edges
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEBusStop.cpp:208
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
const std::string DEFAULT_PEDTYPE_ID
static void buildStop(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter::Stop &stopParameters, GNEDemandElement *stopParent, bool friendlyPosition)
build stop
const std::string & getTagStr() const
get tag assigned to this object in string format
static GNEVehicle * separateEmbeddedRoute(GNEVehicle *vehicle, GNEUndoList *undoList)
separate vehicle and embedded route
bool parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs, std::string errorSuffix, MsgHandler *const errorOutput)
parses attributes common to all stops
void closeVType()
Ends the processing of a vehicle Type.
element is selected
SumoXMLTag tag
The vehicle tag.
void addPersonTrip(const SUMOSAXAttributes &attrs)
add a routing request for a walking or intermodal person
std::vector< PersonPlansValues > myPersonPlanValues
container for person trips loaded values
const int VEHPARS_DEPARTLANE_SET
std::string id
The vehicle type&#39;s id.
void closeVehicleTypeDistribution()
closes (ends) the building of a distribution
void openRouteDistribution(const SUMOSAXAttributes &attrs)
opens a route distribution for reading
Parameterised myLoadedParameterised
Parameterised used for saving loaded generic parameters that aren&#39;t saved in Vehicles or Vehicle Type...
GNENet * getNet() const
get the net object
Definition: GNEViewNet.cpp:927
bool wasSet(int what) const
Returns whether the given parameter was set.
description of a vehicle
static void buildWalkBusStop(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, GNEAdditional *busStop)
build walk using a form edge an a busStop
static void buildVehicleWithEmbeddedRoute(GNEViewNet *viewNet, bool undoDemandElements, SUMOVehicleParameter vehicleParameters, GNEDemandElement *embeddedRouteCopy)
build vehicle with a embedded route
GNEViewNet * getViewNet() const
Returns a pointer to GNEViewNet in which demand element element is located.
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
description of a person type (used in NETEDIT)
static void buildFlowOverRoute(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &vehicleParameters)
build a flow over an existent route
a single trip definition (used by router)
static void buildPersonTripFromTo(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, const std::vector< std::string > &types, const std::vector< std::string > &modes, double arrivalPos)
build trip using a from-to edges
std::string chargingStation
(Optional) charging station if one is assigned to the stop
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
std::string containerstop
(Optional) container stop if one is assigned to the stop
GNEDemandElement * route
arrival route
static void buildWalkEdges(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, double arrivalPos)
build walk using a list of consecutive edges
std::vector< std::string > vTypes
vehicle types
GNERouteHandler(const std::string &file, GNEViewNet *viewNet, bool undoDemandElements=true)
Constructor.
void addWalk(const SUMOSAXAttributes &attrs)
add a fully specified walk
std::string routeID
string for saving parsed Route ID
void addTransport(const SUMOSAXAttributes &attrs)
Processing of a transport.
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1179
A color information.
void insertDemandElement(GNEDemandElement *demandElement)
Insert a demand element element int GNENet container.
Definition: GNENet.cpp:2727
void addContainer(const SUMOSAXAttributes &attrs)
Processing of a container.
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
void closeTrip()
Ends the processing of a trip.
static void buildVehicleOverRoute(GNEViewNet *viewNet, bool undoDemandElements, const SUMOVehicleParameter &vehicleParameters)
build functions
std::string id
The vehicle&#39;s id.
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
static void buildFlowWithEmbeddedRoute(GNEViewNet *viewNet, bool undoDemandElements, SUMOVehicleParameter vehicleParameters, GNEDemandElement *embeddedRouteCopy)
build flow with a embedded route
static void buildPersonTripBusStop(GNEViewNet *viewNet, bool undoDemandElements, GNEDemandElement *personParent, const std::vector< GNEEdge *> &edges, GNEAdditional *busStop, const std::vector< std::string > &types, const std::vector< std::string > &modes)
build trip using a from edge and a busStop