Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNERouteHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// Builds demand objects for netedit
19/****************************************************************************/
20#include <netedit/GNENet.h>
21#include <netedit/GNEUndoList.h>
22#include <netedit/GNEViewNet.h>
30
31#include "GNEContainer.h"
32#include "GNEPerson.h"
33#include "GNEPersonTrip.h"
34#include "GNERide.h"
35#include "GNERoute.h"
37#include "GNERouteHandler.h"
38#include "GNEStop.h"
39#include "GNETranship.h"
40#include "GNETransport.h"
41#include "GNEVehicle.h"
42#include "GNEVType.h"
44#include "GNEWalk.h"
45#include "GNEStopPlan.h"
46
47// ===========================================================================
48// member method definitions
49// ===========================================================================
50
51GNERouteHandler::GNERouteHandler(const std::string& file, GNENet* net, const bool allowUndoRedo, const bool overwrite) :
52 RouteHandler(file, false),
53 myNet(net),
54 myPlanObject(new CommonXMLStructure::SumoBaseObject(nullptr)),
55 myAllowUndoRedo(allowUndoRedo),
56 myOverwrite(overwrite) {
57}
58
59
63
64
65void
67 // check if loaded type is a default type
68 if (DEFAULT_VTYPES.count(vTypeParameter.id) > 0) {
69 // overwrite default vehicle type
71 } else if (!checkDuplicatedDemandElement(SUMO_TAG_VTYPE, vTypeParameter.id)) {
72 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE), vTypeParameter.id));
73 } else {
74 // create vType/pType using myCurrentVType
75 GNEDemandElement* vType = new GNEVType(myNet, vTypeParameter);
76 // check if add this vType to a distribution
77 GNEDemandElement* vTypeDistribution = nullptr;
78 if (sumoBaseObject->getParentSumoBaseObject() && sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VTYPE_DISTRIBUTION) {
80 }
81 if (myAllowUndoRedo) {
82 myNet->getViewNet()->getUndoList()->begin(vType, TL("add ") + vType->getTagStr() + " '" + vTypeParameter.id + "'");
84 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vType, true), true);
85 if (vTypeDistribution) {
86 vTypeDistribution->addDistributionKey(vType, vType->getAttributeDouble(SUMO_ATTR_PROB), myNet->getViewNet()->getUndoList());
87 }
89 } else {
91 if (vTypeDistribution) {
92 vTypeDistribution->addDistributionKey(vType, vType->getAttributeDouble(SUMO_ATTR_PROB));
93 }
94 vType->incRef("buildVType");
95 }
96 }
97}
98
99
100void
101GNERouteHandler::buildVTypeDistribution(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const int deterministic,
102 const std::vector<std::string>& vTypeIDs, const std::vector<double>& probabilities) {
103 // declare vector with vType and their probabilities
104 std::vector<const GNEDemandElement*> vTypes;
105 // first check conditions
107 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE)));
108 } else if (getDistributionElements(sumoBaseObject, SUMO_TAG_VTYPE, vTypeIDs, probabilities, vTypes)) {
109 // create distributions
110 GNEVTypeDistribution* vTypeDistribution = new GNEVTypeDistribution(myNet, id, deterministic);
111 if (myAllowUndoRedo) {
112 myNet->getViewNet()->getUndoList()->begin(vTypeDistribution, TL("add ") + vTypeDistribution->getTagStr() + " '" + id + "'");
114 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vTypeDistribution, true), true);
115 // add all distributions
116 for (int i = 0; i < (int)vTypes.size(); i++) {
117 vTypeDistribution->addDistributionKey(vTypes.at(i), probabilities.at(i), myNet->getViewNet()->getUndoList());
118 }
120 } else {
121 myNet->getAttributeCarriers()->insertDemandElement(vTypeDistribution);
122 // add all distributions directly
123 for (int i = 0; i < (int)vTypes.size(); i++) {
124 vTypeDistribution->addDistributionKey(vTypes.at(i), probabilities.at(i));
125 }
126 vTypeDistribution->incRef("buildVTypeDistribution");
127 }
128 }
129}
130
131
132void
133GNERouteHandler::buildRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, SUMOVehicleClass vClass,
134 const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
135 const double probability, const Parameterised::Map& routeParameters) {
136 // parse edges
137 const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
138 // check conditions
140 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_ROUTE), id));
141 } else if (edges.size() > 0) {
142 // create GNERoute
143 GNEDemandElement* route = new GNERoute(myNet, id, vClass, edges, color, repeat, cycleTime, routeParameters);
144 // check if add this route to a distribution
145 GNEDemandElement* routeDistribution = nullptr;
146 if (sumoBaseObject && sumoBaseObject->getParentSumoBaseObject() && sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_ROUTE_DISTRIBUTION) {
148 }
149 if (myAllowUndoRedo) {
150 myNet->getViewNet()->getUndoList()->begin(route, TL("add ") + route->getTagStr() + " '" + id + "'");
152 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
153 if (routeDistribution) {
154 routeDistribution->addDistributionKey(route, probability, myNet->getViewNet()->getUndoList());
155 }
157 } else {
159 for (const auto& edge : edges) {
160 edge->addChildElement(route);
161 }
162 if (routeDistribution) {
163 routeDistribution->addDistributionKey(route, probability);
164 }
165 route->incRef("buildRoute");
166 }
167 }
168}
169
170
171void
172GNERouteHandler::buildEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::vector<std::string>& edgeIDs,
173 const RGBColor& color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map& routeParameters) {
174 // first create vehicle/flow
175 const SUMOVehicleParameter& vehicleParameters = sumoBaseObject->getParentSumoBaseObject()->getVehicleParameter();
176 const SumoXMLTag vehicleTag = (sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VEHICLE) ? GNE_TAG_VEHICLE_WITHROUTE :
178 sumoBaseObject->getParentSumoBaseObject()->getTag();
179 // parse route edges
180 const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
181 // check if ID is duplicated
182 if ((edges.size() > 0) && !isVehicleIdDuplicated(vehicleParameters.id)) {
183 // obtain type
184 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
185 if (type == nullptr) {
186 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
187 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)edges.front()->getLanes().size() < vehicleParameters.departLane)) {
188 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
189 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
190 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
191 } else {
192 // create vehicle using vehicleParameters
193 GNEDemandElement* vehicle = new GNEVehicle(vehicleTag, myNet, type, vehicleParameters);
194 // create embedded route
195 GNEDemandElement* route = new GNERoute(myNet, vehicle, edges, color, repeat, cycleTime, routeParameters);
196 if (myAllowUndoRedo) {
197 myNet->getViewNet()->getUndoList()->begin(route, TL("add ") + route->getTagStr() + " in '" + vehicle->getID() + "'");
199 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
200 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
202 } else {
205 type->addChildElement(vehicle);
206 vehicle->addChildElement(route);
207 for (const auto& edge : edges) {
208 edge->addChildElement(route);
209 }
210 vehicle->incRef("buildEmbeddedRoute");
211 route->incRef("buildEmbeddedRoute");
212 }
213 }
214 }
215}
216
217
218void
220 const std::vector<std::string>& routeIDs, const std::vector<double>& probabilities) {
221 // declare vector with route and their probabilities
222 std::vector<const GNEDemandElement*> routes;
223 // first check conditions
225 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_ROUTE)));
226 } else if (getDistributionElements(sumoBaseObject, SUMO_TAG_ROUTE, routeIDs, probabilities, routes)) {
227 // create distributions
228 GNERouteDistribution* routeDistribution = new GNERouteDistribution(myNet, id);
229 if (myAllowUndoRedo) {
230 myNet->getViewNet()->getUndoList()->begin(routeDistribution, TL("add ") + routeDistribution->getTagStr() + " '" + id + "'");
232 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(routeDistribution, true), true);
233 // add all distributions
234 for (int i = 0; i < (int)routes.size(); i++) {
235 routeDistribution->addDistributionKey(routes.at(i), probabilities.at(i), myNet->getViewNet()->getUndoList());
236 }
238 } else {
239 myNet->getAttributeCarriers()->insertDemandElement(routeDistribution);
240 // add all distributions directly
241 for (int i = 0; i < (int)routes.size(); i++) {
242 routeDistribution->addDistributionKey(routes.at(i), probabilities.at(i));
243 }
244 routeDistribution->incRef("buildRouteDistribution");
245 }
246 }
247}
248
249
250void
252 // first check if ID is duplicated
253 if (!isVehicleIdDuplicated(vehicleParameters.id)) {
254 // obtain routes and vtypes
255 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
257 if (type == nullptr) {
258 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
259 } else if (route == nullptr) {
260 writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
261 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
262 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
263 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
264 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
265 } else {
266 // create vehicle using vehicleParameters
267 GNEDemandElement* vehicle = new GNEVehicle(SUMO_TAG_VEHICLE, myNet, type, route, vehicleParameters);
268 if (myAllowUndoRedo) {
269 myNet->getViewNet()->getUndoList()->begin(vehicle, TL("add ") + vehicle->getTagStr() + " '" + vehicleParameters.id + "'");
271 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
273 } else {
275 // set vehicle as child of type and Route
276 type->addChildElement(vehicle);
277 route->addChildElement(vehicle);
278 vehicle->incRef("buildVehicleOverRoute");
279 }
280 }
281 }
282}
283
284
285void
287 // first check if ID is duplicated
288 if (!isVehicleIdDuplicated(vehicleParameters.id)) {
289 // obtain routes and vtypes
290 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
292 if (type == nullptr) {
293 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
294 } else if (route == nullptr) {
295 writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
296 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
297 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
298 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
299 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
300 } else {
301 // create flow or trips using vehicleParameters
302 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_ROUTE, myNet, type, route, vehicleParameters);
303 if (myAllowUndoRedo) {
304 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
306 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
308 } else {
310 // set flow as child of type and Route
311 type->addChildElement(flow);
312 route->addChildElement(flow);
313 flow->incRef("buildFlowOverRoute");
314 }
315 }
316 }
317}
318
319
320void
322 const std::string& fromEdgeID, const std::string& toEdgeID) {
323 // parse edges
324 const auto fromEdge = parseEdge(SUMO_TAG_TRIP, fromEdgeID, sumoBaseObject, true);
325 const auto toEdge = parseEdge(SUMO_TAG_TRIP, toEdgeID, sumoBaseObject, false);
326 // set via attribute
327 if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
328 vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
329 }
330 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
331 if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
332 // obtain type
333 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
334 if (type == nullptr) {
335 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
336 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
337 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
338 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
339 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
340 } else {
341 // create trip or flow using tripParameters
342 GNEDemandElement* trip = new GNEVehicle(SUMO_TAG_TRIP, myNet, type, fromEdge, toEdge, vehicleParameters);
343 if (myAllowUndoRedo) {
344 myNet->getViewNet()->getUndoList()->begin(trip, TL("add ") + trip->getTagStr() + " '" + vehicleParameters.id + "'");
346 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(trip, true), true);
348 } else {
350 // set vehicle as child of type
351 type->addChildElement(trip);
352 trip->incRef("buildTrip");
353 // add reference in all edges
354 fromEdge->addChildElement(trip);
355 toEdge->addChildElement(trip);
356 }
357 }
358 }
359}
360
361
362void
364 const std::string& fromJunctionID, const std::string& toJunctionID) {
365 // parse junctions
366 const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
367 const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
368 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
369 if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
370 // obtain type
371 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
372 if (type == nullptr) {
373 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
374 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
375 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
376 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
377 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
378 } else {
379 // create trip using vehicleParameters
380 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
381 if (myAllowUndoRedo) {
382 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
384 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
386 } else {
388 // set vehicle as child of type
389 type->addChildElement(flow);
390 flow->incRef("buildFlow");
391 // add reference in all junctions
392 fromJunction->addChildElement(flow);
393 toJunction->addChildElement(flow);
394 }
395 }
396 }
397}
398
399
400void
402 const std::string& fromTAZID, const std::string& toTAZID) {
403 // parse TAZs
404 const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
405 const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
406 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
407 if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
408 // obtain type
409 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
410 if (type == nullptr) {
411 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
412 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
413 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
414 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
415 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
416 } else {
417 // create trip using vehicleParameters
418 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
419 if (myAllowUndoRedo) {
420 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
422 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
424 } else {
426 // set vehicle as child of type
427 type->addChildElement(flow);
428 flow->incRef("buildFlow");
429 // add reference in all TAZs
430 fromTAZ->addChildElement(flow);
431 toTAZ->addChildElement(flow);
432 }
433 }
434 }
435}
436
437
438void
440 const std::string& fromEdgeID, const std::string& toEdgeID) {
441 // parse edges
442 const auto fromEdge = parseEdge(SUMO_TAG_FLOW, fromEdgeID, sumoBaseObject, true);
443 const auto toEdge = parseEdge(SUMO_TAG_FLOW, toEdgeID, sumoBaseObject, false);
444 // set via attribute
445 if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
446 vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
447 }
448 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
449 if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
450 // obtain type
451 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
452 if (type == nullptr) {
453 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
454 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
455 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
456 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
457 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
458 } else {
459 // create trip or flow using tripParameters
460 GNEDemandElement* flow = new GNEVehicle(SUMO_TAG_FLOW, myNet, type, fromEdge, toEdge, vehicleParameters);
461 if (myAllowUndoRedo) {
462 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
464 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
466 } else {
468 // set vehicle as child of type
469 type->addChildElement(flow);
470 flow->incRef("buildFlow");
471 // add reference in all edges
472 fromEdge->addChildElement(flow);
473 toEdge->addChildElement(flow);
474 }
475 }
476 }
477}
478
479
480void
482 const std::string& fromJunctionID, const std::string& toJunctionID) {
483 // parse junctions
484 const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
485 const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
486 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
487 if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
488 // obtain type
489 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
490 if (type == nullptr) {
491 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
492 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
493 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
494 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
495 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
496 } else {
497 // create flow using vehicleParameters
498 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
499 if (myAllowUndoRedo) {
500 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
502 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
504 } else {
506 // set vehicle as child of type
507 type->addChildElement(flow);
508 flow->incRef("buildFlow");
509 // add reference in all junctions
510 fromJunction->addChildElement(flow);
511 toJunction->addChildElement(flow);
512 }
513 }
514 }
515}
516
517
518void
520 const std::string& fromTAZID, const std::string& toTAZID) {
521 // parse TAZs
522 const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
523 const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
524 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
525 if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
526 // obtain type
527 GNEDemandElement* type = getType(vehicleParameters.vtypeid);
528 if (type == nullptr) {
529 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
530 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
531 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
532 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
533 writeError(TLF("Invalid % used in % '%'. % is greater than type %", toString(SUMO_ATTR_DEPARTSPEED), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departSpeed), toString(SUMO_ATTR_MAXSPEED)));
534 } else {
535 // create flow using vehicleParameters
536 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
537 if (myAllowUndoRedo) {
538 myNet->getViewNet()->getUndoList()->begin(flow, TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
540 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
542 } else {
544 // set vehicle as child of type
545 type->addChildElement(flow);
546 flow->incRef("buildFlow");
547 // add reference in all TAZs
548 fromTAZ->addChildElement(flow);
549 toTAZ->addChildElement(flow);
550 }
551 }
552 }
553}
554
555
556void
558 // first check if ID is duplicated
559 if (!isPersonIdDuplicated(personParameters.id)) {
560 // obtain type
561 GNEDemandElement* type = getType(personParameters.vtypeid);
562 if (type == nullptr) {
563 writeError(TLF("Invalid vehicle type '%' used in % '%'.", personParameters.vtypeid, toString(personParameters.tag), personParameters.id));
564 } else {
565 // create person using personParameters
566 GNEDemandElement* person = new GNEPerson(SUMO_TAG_PERSON, myNet, type, personParameters);
567 if (myAllowUndoRedo) {
568 myNet->getViewNet()->getUndoList()->begin(person, TL("add ") + person->getTagStr() + " '" + personParameters.id + "'");
570 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
572 } else {
574 // set person as child of type
575 type->addChildElement(person);
576 person->incRef("buildPerson");
577 }
578 }
579 }
580}
581
582
583void
584GNERouteHandler::buildPersonFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personFlowParameters) {
585 // first check if ID is duplicated
586 if (!isPersonIdDuplicated(personFlowParameters.id)) {
587 // obtain type
588 GNEDemandElement* type = getType(personFlowParameters.vtypeid);
589 if (type == nullptr) {
590 writeError(TLF("Invalid vehicle type '%' used in % '%'.", personFlowParameters.vtypeid, toString(personFlowParameters.tag), personFlowParameters.id));
591 } else {
592 // create personFlow using personFlowParameters
593 GNEDemandElement* personFlow = new GNEPerson(SUMO_TAG_PERSONFLOW, myNet, type, personFlowParameters);
594 if (myAllowUndoRedo) {
595 myNet->getViewNet()->getUndoList()->begin(personFlow, TL("add ") + personFlow->getTagStr() + " '" + personFlowParameters.id + "'");
597 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personFlow, true), true);
599 } else {
601 // set personFlow as child of type
602 type->addChildElement(personFlow);
603 personFlow->incRef("buildPersonFlow");
604 }
605 }
606 }
607}
608
609
610void
612 const double arrivalPos, const std::vector<std::string>& types, const std::vector<std::string>& modes,
613 const std::vector<std::string>& lines, const double walkFactor, const std::string& group) {
614 // get values
615 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
616 const auto tagIcon = GNEDemandElementPlan::getPersonTripTagIcon(planParameters);
617 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
618 // check conditions
619 if (personParent == nullptr) {
620 WRITE_ERROR(TL("invalid person parent"));
621 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
622 WRITE_ERROR(TL("invalid combination for personTrip"));
623 } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
624 // build person trip
625 GNEDemandElement* personTrip = new GNEPersonTrip(myNet, tagIcon.first, tagIcon.second, personParent, planParents,
626 arrivalPos, types, modes, lines, walkFactor, group);
627 // continue depending of undo.redo
628 if (myAllowUndoRedo) {
629 myNet->getViewNet()->getUndoList()->begin(personTrip, TLF("add % in '%'", personTrip->getTagStr(), personParent->getID()));
631 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
633 } else {
635 // set child references
636 personParent->addChildElement(personTrip);
637 planParents.addChildElements(personTrip);
638 personTrip->incRef("buildPersonTrip");
639 }
640 }
641}
642
643
644void
646 const double arrivalPos, const double speed, const SUMOTime duration) {
647 // get values
648 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
649 const auto tagIcon = GNEDemandElementPlan::getWalkTagIcon(planParameters);
650 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
651 // check conditions
652 if (personParent == nullptr) {
653 WRITE_ERROR(TL("invalid person parent"));
654 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
655 WRITE_ERROR(TL("invalid combination for personTrip"));
656 } else if (speed < 0) {
658 } else if (duration < 0) {
660 } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
661 // build person trip
662 GNEDemandElement* walk = new GNEWalk(myNet, tagIcon.first, tagIcon.second, personParent, planParents, arrivalPos, speed, duration);
663 // continue depending of undo.redo
664 if (myAllowUndoRedo) {
665 myNet->getViewNet()->getUndoList()->begin(walk, TLF("add % in '%'", walk->getTagStr(), personParent->getID()));
667 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
669 } else {
671 // set child references
672 personParent->addChildElement(walk);
673 planParents.addChildElements(walk);
674 walk->incRef("buildWalk");
675 }
676 }
677}
678
679
680void
682 const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
683 // get values
684 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
685 const auto tagIcon = GNEDemandElementPlan::getRideTagIcon(planParameters);
686 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
687 // check conditions
688 if (personParent == nullptr) {
689 writeError(TL("invalid person parent"));
690 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
691 writeError(TL("invalid combination for ride"));
692 } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
693 // build ride
694 GNEDemandElement* ride = new GNERide(myNet, tagIcon.first, tagIcon.second, personParent, planParents, arrivalPos, lines, group);
695 // continue depending of undo-redo
696 if (myAllowUndoRedo) {
697 myNet->getViewNet()->getUndoList()->begin(ride, TLF("add % in '%'", ride->getTagStr(), personParent->getID()));
699 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
701 } else {
703 // set child references
704 personParent->addChildElement(ride);
705 planParents.addChildElements(ride);
706 ride->incRef("buildRide");
707 }
708 }
709}
710
711
712void
714 // first check if ID is duplicated
715 if (!isContainerIdDuplicated(containerParameters.id)) {
716 // obtain type
717 GNEDemandElement* type = getType(containerParameters.vtypeid);
718 if (type == nullptr) {
719 writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerParameters.vtypeid, toString(containerParameters.tag), containerParameters.id));
720 } else {
721 // create container using containerParameters
722 GNEDemandElement* container = new GNEContainer(SUMO_TAG_CONTAINER, myNet, type, containerParameters);
723 if (myAllowUndoRedo) {
724 myNet->getViewNet()->getUndoList()->begin(container, TL("add ") + container->getTagStr() + " '" + container->getID() + "'");
726 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(container, true), true);
728 } else {
730 // set container as child of type
731 type->addChildElement(container);
732 container->incRef("buildContainer");
733 }
734 }
735 }
736}
737
738
739void
740GNERouteHandler::buildContainerFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerFlowParameters) {
741 // first check if ID is duplicated
742 if (!isContainerIdDuplicated(containerFlowParameters.id)) {
743 // obtain type
744 GNEDemandElement* type = getType(containerFlowParameters.vtypeid);
745 if (type == nullptr) {
746 writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerFlowParameters.vtypeid, toString(containerFlowParameters.tag), containerFlowParameters.id));
747 } else {
748 // create containerFlow using containerFlowParameters
749 GNEDemandElement* containerFlow = new GNEContainer(SUMO_TAG_CONTAINERFLOW, myNet, type, containerFlowParameters);
750 if (myAllowUndoRedo) {
751 myNet->getViewNet()->getUndoList()->begin(containerFlow, TL("add ") + containerFlow->getTagStr() + " '" + containerFlow->getID() + "'");
753 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(containerFlow, true), true);
755 } else {
757 // set containerFlow as child of type
758 type->addChildElement(containerFlow);
759 containerFlow->incRef("buildContainerFlow");
760 }
761 }
762 }
763}
764
765
766void
768 const double arrivalPos, const std::vector<std::string>& lines, const std::string& group) {
769 // get values
770 GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
771 const auto tagIcon = GNEDemandElementPlan::getTransportTagIcon(planParameters);
772 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
773 // check conditions
774 if (containerParent == nullptr) {
775 WRITE_ERROR(TL("invalid container parent"));
776 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
777 WRITE_ERROR(TL("invalid combination for personTrip"));
778 } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
779 // build transport
780 GNEDemandElement* transport = new GNETransport(myNet, tagIcon.first, tagIcon.second, containerParent, planParents, arrivalPos, lines, group);
781 // continue depending of undo-redo
782 if (myAllowUndoRedo) {
783 myNet->getViewNet()->getUndoList()->begin(transport, TLF("add % in '%'", transport->getTagStr(), containerParent->getID()));
785 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
787 } else {
789 // set child references
790 containerParent->addChildElement(transport);
791 planParents.addChildElements(transport);
792 transport->incRef("buildTransport");
793 }
794 }
795}
796
797
798void
800 const double arrivalPosition, const double departPosition, const double speed, const SUMOTime duration) {
801 // get values
802 GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
803 const auto tagIcon = GNEDemandElementPlan::getTranshipTagIcon(planParameters);
804 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
805 // check conditions
806 if (containerParent == nullptr) {
807 WRITE_ERROR(TL("invalid container parent"));
808 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
809 WRITE_ERROR(TL("invalid combination for personTrip"));
810 } else if (speed < 0) {
812 } else if (duration < 0) {
814 } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
815 // build tranship
816 GNEDemandElement* tranship = new GNETranship(myNet, tagIcon.first, tagIcon.second, containerParent, planParents,
817 arrivalPosition, departPosition, speed, duration);
818 // continue depending of undo-redo
819 if (myAllowUndoRedo) {
820 myNet->getViewNet()->getUndoList()->begin(tranship, TLF("add % in '%'", tranship->getTagStr(), containerParent->getID()));
822 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
824 } else {
826 // set child references
827 containerParent->addChildElement(tranship);
828 planParents.addChildElements(tranship);
829 tranship->incRef("buildTranship");
830 }
831 }
832}
833
834
835void
837 const double endPos, const SUMOTime duration, const SUMOTime until,
838 const std::string& actType, const bool friendlyPos, const int parameterSet) {
839 // get values
840 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
841 const auto tagIcon = GNEDemandElementPlan::getPersonStopTagIcon(planParameters);
842 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
843 // check conditions
844 if (personParent == nullptr) {
845 WRITE_ERROR(TL("invalid person parent"));
846 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
847 WRITE_ERROR(TL("invalid combination for person stop"));
848 } else if (planParents.checkIntegrity(tagIcon.first, personParent, planParameters)) {
849 // build person stop
850 GNEDemandElement* stopPlan = new GNEStopPlan(myNet, tagIcon.first, tagIcon.second, personParent, planParents,
851 endPos, duration, until, actType, friendlyPos, parameterSet);
852 // continue depending of undo-redo
853 if (myAllowUndoRedo) {
854 myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), personParent->getID()));
856 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
858 } else {
860 // set child references
861 personParent->addChildElement(stopPlan);
862 planParents.addChildElements(stopPlan);
863 stopPlan->incRef("buildPersonStop");
864 }
865 }
866}
867
868
869void
871 const double endPos, const SUMOTime duration,
872 const SUMOTime until, const std::string& actType, const bool friendlyPos, const int parameterSet) {
873 // get values
874 GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
875 const auto tagIcon = GNEDemandElementPlan::getContainerStopTagIcon(planParameters);
876 GNEPlanParents planParents = GNEPlanParents(planParameters, myNet->getAttributeCarriers());
877 // check conditions
878 if (containerParent == nullptr) {
879 WRITE_ERROR(TL("invalid container parent"));
880 } else if (tagIcon.first == SUMO_TAG_NOTHING) {
881 WRITE_ERROR(TL("invalid combination for containerStop"));
882 } else if (planParents.checkIntegrity(tagIcon.first, containerParent, planParameters)) {
883 // build container stop
884 GNEDemandElement* stopPlan = new GNEStopPlan(myNet, tagIcon.first, tagIcon.second, containerParent, planParents,
885 endPos, duration, until, actType, friendlyPos, parameterSet);
886 // continue depending of undo-redo
887 if (myAllowUndoRedo) {
888 myNet->getViewNet()->getUndoList()->begin(stopPlan, TLF("add % in '%'", stopPlan->getTagStr(), containerParent->getID()));
890 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stopPlan, true), true);
892 } else {
894 // set child references
895 containerParent->addChildElement(stopPlan);
896 planParents.addChildElements(stopPlan);
897 stopPlan->incRef("buildContainerStop");
898 }
899 }
900}
901
902
903void
905 const SUMOVehicleParameter::Stop& stopParameters) {
906 // get obj parent
907 const auto objParent = sumoBaseObject->getParentSumoBaseObject();
908 // continue depending of objParent
909 if (objParent == nullptr) {
910 WRITE_ERROR(TL("Stops needs a parent"));
911 } else if ((objParent->getTag() == SUMO_TAG_PERSON) || (objParent->getTag() == SUMO_TAG_PERSONFLOW)) {
912 buildPersonStop(sumoBaseObject, planParameters, stopParameters.endPos,
913 stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
914 } else if ((objParent->getTag() == SUMO_TAG_CONTAINER) || (objParent->getTag() == SUMO_TAG_CONTAINERFLOW)) {
915 buildContainerStop(sumoBaseObject, planParameters, stopParameters.endPos,
916 stopParameters.duration, stopParameters.until, stopParameters.actType, stopParameters.friendlyPos, stopParameters.parametersSet);
917 } else {
918 // get vehicle tag
919 SumoXMLTag vehicleTag = objParent->getTag();
920 if (vehicleTag == SUMO_TAG_VEHICLE) {
921 // check if vehicle is placed over route or with embedded route
922 if (!objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
923 vehicleTag = GNE_TAG_VEHICLE_WITHROUTE;
924 }
925 } else if (vehicleTag == SUMO_TAG_FLOW) {
926 if (objParent->hasStringAttribute(SUMO_ATTR_ROUTE)) {
927 vehicleTag = GNE_TAG_FLOW_ROUTE;
928 } else if (objParent->hasStringAttribute(SUMO_ATTR_FROM) && objParent->hasStringAttribute(SUMO_ATTR_TO)) {
929 vehicleTag = SUMO_TAG_FLOW;
930 } else {
931 vehicleTag = GNE_TAG_FLOW_WITHROUTE;
932 }
933 }
934 // get stop parent
935 GNEDemandElement* stopParent = myNet->getAttributeCarriers()->retrieveDemandElement(vehicleTag, objParent->getStringAttribute(SUMO_ATTR_ID), false);
936 // check if stopParent exist
937 if (stopParent) {
938 // flag for waypoint (is like a stop, but with extra attribute speed)
939 bool waypoint = false;
940 // avoid waypoints for person and containers
941 if (!stopParent->getTagProperty().isPerson() && !stopParent->getTagProperty().isContainer()) {
942 waypoint = (sumoBaseObject->getStopParameter().parametersSet & STOP_SPEED_SET) || (sumoBaseObject->getStopParameter().speed > 0);
943 }
944 // declare pointers to parent elements
945 GNEAdditional* stoppingPlace = nullptr;
946 GNELane* lane = nullptr;
947 GNEEdge* edge = nullptr;
948 // declare stopTagType
949 SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
950 bool validParentDemandElement = true;
951 // check conditions
952 if (stopParameters.busstop.size() > 0) {
953 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
954 stopTagType = waypoint ? GNE_TAG_WAYPOINT_BUSSTOP : GNE_TAG_STOP_BUSSTOP;
955 // check if is a train stop
956 if (stoppingPlace == nullptr) {
957 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, stopParameters.busstop, false);
958 stopTagType = waypoint ? GNE_TAG_WAYPOINT_TRAINSTOP : GNE_TAG_STOP_TRAINSTOP;
959 }
960 // containers cannot stops in busStops
961 if (stopParent->getTagProperty().isContainer()) {
962 writeError(TL("Containers don't support stops at busStops or trainStops"));
963 validParentDemandElement = false;
964 }
965 } else if (stopParameters.containerstop.size() > 0) {
966 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
968 // persons cannot stops in containerStops
969 if (stopParent->getTagProperty().isPerson()) {
970 writeError(TL("Persons don't support stops at containerStops"));
971 validParentDemandElement = false;
972 }
973 } else if (stopParameters.chargingStation.size() > 0) {
976 // check person and containers
977 if (stopParent->getTagProperty().isPerson()) {
978 writeError(TL("Persons don't support stops at chargingStations"));
979 validParentDemandElement = false;
980 } else if (stopParent->getTagProperty().isContainer()) {
981 writeError(TL("Containers don't support stops at chargingStations"));
982 validParentDemandElement = false;
983 }
984 } else if (stopParameters.parkingarea.size() > 0) {
985 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
987 // check person and containers
988 if (stopParent->getTagProperty().isPerson()) {
989 writeError(TL("Persons don't support stops at parkingAreas"));
990 validParentDemandElement = false;
991 } else if (stopParent->getTagProperty().isContainer()) {
992 writeError(TL("Containers don't support stops at parkingAreas"));
993 validParentDemandElement = false;
994 }
995 } else if (stopParameters.lane.size() > 0) {
996 lane = myNet->getAttributeCarriers()->retrieveLane(stopParameters.lane, false);
997 stopTagType = waypoint ? GNE_TAG_WAYPOINT_LANE : GNE_TAG_STOP_LANE;
998 } else if (stopParameters.edge.size() > 0) {
999 edge = myNet->getAttributeCarriers()->retrieveEdge(stopParameters.edge, false);
1000 // check vehicles
1001 if (stopParent->getTagProperty().isVehicle()) {
1002 writeError(TL("vehicles don't support stops at edges"));
1003 validParentDemandElement = false;
1004 }
1005 }
1006 // overwrite lane with edge parent if we're handling a personStop
1007 if (lane && (stopParent->getTagProperty().isPerson() || stopParent->getTagProperty().isContainer())) {
1008 edge = lane->getParentEdge();
1009 lane = nullptr;
1010 }
1011 // first check that parent is valid
1012 if (validParentDemandElement) {
1013 // check if values are correct
1014 if (stoppingPlace && lane && edge) {
1015 writeError(TL("A stop must be defined either over a stoppingPlace, a edge or a lane"));
1016 } else if (!stoppingPlace && !lane && !edge) {
1017 writeError(TL("A stop requires only a stoppingPlace, edge or lane"));
1018 } else if (stoppingPlace) {
1019 // create stop using stopParameters and stoppingPlace
1020 GNEDemandElement* stop = nullptr;
1021 if (stopParent->getTagProperty().isPerson()) {
1022 if (stoppingPlace->getTagProperty().getTag() == SUMO_TAG_BUS_STOP) {
1023 stop = new GNEStop(GNE_TAG_STOPPERSON_BUSSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1024 } else {
1025 stop = new GNEStop(GNE_TAG_STOPPERSON_TRAINSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1026 }
1027 } else if (stopParent->getTagProperty().isContainer()) {
1028 stop = new GNEStop(GNE_TAG_STOPCONTAINER_CONTAINERSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1029 } else {
1030 stop = new GNEStop(stopTagType, myNet, stopParent, stoppingPlace, stopParameters);
1031 }
1032 // add it depending of undoDemandElements
1033 if (myAllowUndoRedo) {
1034 myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1036 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1038 } else {
1040 stoppingPlace->addChildElement(stop);
1041 stopParent->addChildElement(stop);
1042 stop->incRef("buildStoppingPlaceStop");
1043 }
1044 } else if (lane) {
1045 // create stop using stopParameters and lane (only for vehicles)
1046 GNEDemandElement* stop = new GNEStop(stopTagType, myNet, stopParent, lane, stopParameters);
1047 // add it depending of undoDemandElements
1048 if (myAllowUndoRedo) {
1049 myNet->getViewNet()->getUndoList()->begin(stop, TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1051 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1053 } else {
1055 lane->addChildElement(stop);
1056 stopParent->addChildElement(stop);
1057 stop->incRef("buildLaneStop");
1058 }
1059 }
1060 }
1061 }
1062 }
1063}
1064
1065
1066bool
1068 GNEAttributesCreator* personPlanAttributes, GNEPlanCreator* planCreator,
1069 const bool centerAfterCreation) {
1070 // first check if person is valid
1071 if (personParent == nullptr) {
1072 return false;
1073 }
1074 // clear and set person object
1076 myPlanObject->setTag(personParent->getTagProperty().getTag());
1078 // declare personPlan object
1080 // get person plan attributes
1081 personPlanAttributes->getAttributesAndValues(personPlanObject, true);
1082 // get attributes
1083 const std::vector<std::string> types = personPlanObject->hasStringListAttribute(SUMO_ATTR_VTYPES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_VTYPES) :
1084 personPlanObject->hasStringAttribute(SUMO_ATTR_VTYPES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_VTYPES)) :
1085 std::vector<std::string>();
1086 const std::vector<std::string> modes = personPlanObject->hasStringListAttribute(SUMO_ATTR_MODES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_MODES) :
1087 personPlanObject->hasStringAttribute(SUMO_ATTR_MODES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_MODES)) :
1088 std::vector<std::string>();
1089 const std::vector<std::string> lines = personPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1090 personPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(personPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1091 std::vector<std::string>();
1092 const double arrivalPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1093 personPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1094 -1;
1095 const double endPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1096 personPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(personPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1097 planCreator->getClickedPositionOverLane();
1098 const SUMOTime duration = personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? personPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1099 personPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1100 0;
1101 const SUMOTime until = personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? personPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1102 personPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(personPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1103 0;
1104 const std::string actType = personPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? personPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1105 const bool friendlyPos = personPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? personPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1106 personPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(personPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1107 false;
1108 const double walkFactor = personPlanObject->hasDoubleAttribute(SUMO_ATTR_WALKFACTOR) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_WALKFACTOR) : 0;
1109 const std::string group = personPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? personPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1110 const double speed = personPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) : 0;
1111 // build depending of plan type
1112 if (planTemplate->getTagProperty().isPlanWalk()) {
1113 buildWalk(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, speed, duration);
1114 } else if (planTemplate->getTagProperty().isPlanPersonTrip()) {
1115 buildPersonTrip(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, types, modes, lines, walkFactor, group);
1116 } else if (planTemplate->getTagProperty().isPlanRide()) {
1117 buildRide(personPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1118 } else if (planTemplate->getTagProperty().isPlanStopPerson()) {
1119 // set specific stop parameters
1120 int parameterSet = 0;
1121 if (personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1122 parameterSet |= STOP_DURATION_SET;
1123 }
1124 if (personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1125 parameterSet |= STOP_UNTIL_SET;
1126 }
1127 buildPersonStop(personPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1128 }
1129 // get person
1130 const auto person = myNet->getAttributeCarriers()->retrieveDemandElement(personPlanObject->getParentSumoBaseObject()->getTag(),
1131 personPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1132 if (person) {
1133 // center view after creation
1134 if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(person->getPositionInView())) {
1135 myNet->getViewNet()->centerTo(person->getPositionInView(), false);
1136 }
1137 }
1138 delete personPlanObject;
1139 return true;
1140}
1141
1142
1143bool
1145 GNEAttributesCreator* containerPlanAttributes, GNEPlanCreator* planCreator,
1146 const bool centerAfterCreation) {
1147 // first check if container is valid
1148 if (containerParent == nullptr) {
1149 return false;
1150 }
1151 // clear and set container object
1153 myPlanObject->setTag(containerParent->getTagProperty().getTag());
1154 myPlanObject->addStringAttribute(SUMO_ATTR_ID, containerParent->getID());
1155 // declare containerPlan object
1157 // get container plan attributes
1158 containerPlanAttributes->getAttributesAndValues(containerPlanObject, true);
1159 // get attributes
1160 const double speed = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) :
1161 containerPlanObject->hasStringAttribute(SUMO_ATTR_SPEED) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_SPEED)) :
1162 0;
1163 const std::vector<std::string> lines = containerPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? containerPlanObject->getStringListAttribute(SUMO_ATTR_LINES) :
1164 containerPlanObject->hasStringAttribute(SUMO_ATTR_LINES) ? GNEAttributeCarrier::parse<std::vector<std::string> >(containerPlanObject->getStringAttribute(SUMO_ATTR_LINES)) :
1165 std::vector<std::string>();
1166 const double departPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_DEPARTPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS) :
1167 containerPlanObject->hasStringAttribute(SUMO_ATTR_DEPARTPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_DEPARTPOS)) :
1168 -1;
1169 const double arrivalPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) :
1170 containerPlanObject->hasStringAttribute(SUMO_ATTR_ARRIVALPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ARRIVALPOS)) :
1171 -1;
1172 const double endPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ENDPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ENDPOS) :
1173 containerPlanObject->hasStringAttribute(SUMO_ATTR_ENDPOS) ? GNEAttributeCarrier::parse<double>(containerPlanObject->getStringAttribute(SUMO_ATTR_ENDPOS)) :
1174 planCreator->getClickedPositionOverLane();
1175 const SUMOTime duration = containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_DURATION) :
1176 containerPlanObject->hasStringAttribute(SUMO_ATTR_DURATION) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_DURATION)) :
1177 0;
1178 const SUMOTime until = containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL) ? containerPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL) :
1179 containerPlanObject->hasStringAttribute(SUMO_ATTR_UNTIL) ? GNEAttributeCarrier::parse<SUMOTime>(containerPlanObject->getStringAttribute(SUMO_ATTR_UNTIL)) :
1180 0;
1181 const std::string actType = containerPlanObject->hasStringAttribute(SUMO_ATTR_ACTTYPE) ? containerPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE) : "";
1182 const bool friendlyPos = containerPlanObject->hasBoolAttribute(SUMO_ATTR_FRIENDLY_POS) ? containerPlanObject->getBoolAttribute(SUMO_ATTR_FRIENDLY_POS) :
1183 containerPlanObject->hasStringAttribute(SUMO_ATTR_FRIENDLY_POS) ? GNEAttributeCarrier::parse<bool>(containerPlanObject->getStringAttribute(SUMO_ATTR_FRIENDLY_POS)) :
1184 false;
1185 const std::string group = containerPlanObject->hasStringAttribute(SUMO_ATTR_GROUP) ? containerPlanObject->getStringAttribute(SUMO_ATTR_GROUP) : "";
1186 // build depending of plan type
1187 if (planTemplate->getTagProperty().isPlanTranship()) {
1188 buildTranship(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, departPos, speed, duration);
1189 } else if (planTemplate->getTagProperty().isPlanTransport()) {
1190 buildTransport(containerPlanObject, planCreator->getPlanParameteres(), arrivalPos, lines, group);
1191 } else if (planTemplate->getTagProperty().isPlanStopContainer()) {
1192 // set stops specific parameters
1193 int parameterSet = 0;
1194 if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1195 parameterSet |= STOP_DURATION_SET;
1196 }
1197 if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1198 parameterSet |= STOP_UNTIL_SET;
1199 }
1200 buildContainerStop(containerPlanObject, planCreator->getPlanParameteres(), endPos, duration, until, actType, friendlyPos, parameterSet);
1201 }
1202 // get container
1203 const auto container = myNet->getAttributeCarriers()->retrieveDemandElement(containerPlanObject->getParentSumoBaseObject()->getTag(),
1204 containerPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1205 if (container) {
1206 // center view after creation
1207 if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(container->getPositionInView())) {
1208 myNet->getViewNet()->centerTo(container->getPositionInView(), false);
1209 }
1210 }
1211 delete containerPlanObject;
1212 return true;
1213}
1214
1215
1216void
1218 const auto& tagProperty = originalPlan->getTagProperty();
1219 // clear and set container object
1221 myPlanObject->setTag(newParent->getTagProperty().getTag());
1223 // declare personPlan object for adding all attributes
1225 planObject->setTag(tagProperty.getTag());
1226 // declare parameters
1228 // from-to elements
1229 if (tagProperty.planFromEdge()) {
1230 planParameters.fromEdge = originalPlan->getAttribute(SUMO_ATTR_FROM);
1231 }
1232 if (tagProperty.planToEdge()) {
1233 planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_TO);
1234 }
1235 if (tagProperty.planFromJunction()) {
1236 planParameters.fromJunction = originalPlan->getAttribute(SUMO_ATTR_FROM_JUNCTION);
1237 }
1238 if (tagProperty.planToJunction()) {
1239 planParameters.toJunction = originalPlan->getAttribute(SUMO_ATTR_TO_JUNCTION);
1240 }
1241 if (tagProperty.planFromTAZ()) {
1242 planParameters.fromTAZ = originalPlan->getAttribute(SUMO_ATTR_FROM_TAZ);
1243 }
1244 if (tagProperty.planToTAZ()) {
1245 planParameters.toTAZ = originalPlan->getAttribute(SUMO_ATTR_TO_TAZ);
1246 }
1247 if (tagProperty.planFromBusStop()) {
1248 planParameters.fromBusStop = originalPlan->getAttribute(GNE_ATTR_FROM_BUSSTOP);
1249 }
1250 if (tagProperty.planToBusStop()) {
1251 planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1252 }
1253 if (tagProperty.planFromTrainStop()) {
1254 planParameters.fromTrainStop = originalPlan->getAttribute(GNE_ATTR_FROM_TRAINSTOP);
1255 }
1256 if (tagProperty.planToTrainStop()) {
1257 planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1258 }
1259 if (tagProperty.planFromContainerStop()) {
1260 planParameters.fromContainerStop = originalPlan->getAttribute(GNE_ATTR_FROM_CONTAINERSTOP);
1261 }
1262 if (tagProperty.planToContainerStop()) {
1263 planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1264 }
1265 // single elements
1266 if (tagProperty.planEdge()) {
1267 planParameters.toEdge = originalPlan->getAttribute(SUMO_ATTR_EDGE);
1268 }
1269 if (tagProperty.planBusStop()) {
1270 planParameters.toBusStop = originalPlan->getAttribute(SUMO_ATTR_BUS_STOP);
1271 }
1272 if (tagProperty.planTrainStop()) {
1273 planParameters.toTrainStop = originalPlan->getAttribute(SUMO_ATTR_TRAIN_STOP);
1274 }
1275 if (tagProperty.planContainerStop()) {
1276 planParameters.toContainerStop = originalPlan->getAttribute(SUMO_ATTR_CONTAINER_STOP);
1277 }
1278 // route
1279 if (tagProperty.planRoute()) {
1280 planParameters.toRoute = originalPlan->getAttribute(SUMO_ATTR_ROUTE);
1281 }
1282 // path
1283 if (tagProperty.planConsecutiveEdges()) {
1284 planParameters.consecutiveEdges = GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(SUMO_ATTR_EDGES));
1285 }
1286 // other elements
1287 planObject->addTimeAttribute(SUMO_ATTR_DURATION, 60);
1288 planObject->addTimeAttribute(SUMO_ATTR_UNTIL, 0);
1291 planObject->addDoubleAttribute(SUMO_ATTR_ENDPOS, 0);
1292 planObject->addDoubleAttribute(SUMO_ATTR_SPEED, 1.39);
1293 planObject->addBoolAttribute(SUMO_ATTR_FRIENDLY_POS, false);
1294 // add rest of attributes
1295 for (const auto& attrProperty : tagProperty) {
1296 if (!planObject->hasStringAttribute(attrProperty.getAttr())) {
1297 if (attrProperty.isFloat()) {
1298 if (!originalPlan->getAttribute(attrProperty.getAttr()).empty()) {
1299 planObject->addDoubleAttribute(attrProperty.getAttr(), originalPlan->getAttributeDouble(attrProperty.getAttr()));
1300 }
1301 } else if (attrProperty.isSUMOTime()) {
1302 if (!originalPlan->getAttribute(attrProperty.getAttr()).empty()) {
1303 planObject->addTimeAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<SUMOTime>(originalPlan->getAttribute(attrProperty.getAttr())));
1304 }
1305 } else if (attrProperty.isBool()) {
1306 planObject->addBoolAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<bool>(originalPlan->getAttribute(attrProperty.getAttr())));
1307 } else if (attrProperty.isList()) {
1308 planObject->addStringListAttribute(attrProperty.getAttr(), GNEAttributeCarrier::parse<std::vector<std::string> >(originalPlan->getAttribute(attrProperty.getAttr())));
1309 } else {
1310 planObject->addStringAttribute(attrProperty.getAttr(), originalPlan->getAttribute(attrProperty.getAttr()));
1311 }
1312 }
1313 }
1314 // create plan
1315 if (tagProperty.isPlanPersonTrip()) {
1316 buildPersonTrip(planObject, planParameters,
1322 planObject->getStringAttribute(SUMO_ATTR_GROUP));
1323 } else if (tagProperty.isPlanWalk()) {
1324 buildWalk(planObject, planParameters,
1328 } else if (tagProperty.isPlanRide()) {
1329 buildRide(planObject, planParameters,
1332 planObject->getStringAttribute(SUMO_ATTR_GROUP));
1333 } else if (tagProperty.isPlanStopPerson()) {
1334 // set parameters
1335 int parameterSet = 0;
1336 if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1337 parameterSet |= STOP_DURATION_SET;
1338 }
1339 if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1340 parameterSet |= STOP_UNTIL_SET;
1341 }
1342 buildPersonStop(planObject, planParameters,
1345 planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1348 parameterSet);
1349 } else if (tagProperty.isPlanTransport()) {
1350 buildTransport(planObject, planParameters,
1353 planObject->getStringAttribute(SUMO_ATTR_GROUP));
1354 } else if (tagProperty.isPlanTranship()) {
1355 buildTranship(planObject, planParameters,
1360 } else if (tagProperty.isPlanStopContainer()) {
1361 // set parameters
1362 int parameterSet = 0;
1363 if (planObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1364 parameterSet |= STOP_DURATION_SET;
1365 }
1366 if (planObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1367 parameterSet |= STOP_UNTIL_SET;
1368 }
1369 buildContainerStop(planObject, planParameters,
1372 planObject->getTimeAttribute(SUMO_ATTR_UNTIL),
1375 parameterSet);
1376 } else {
1377 throw ProcessError("Invalid plan for duplicating");
1378 }
1379}
1380
1381
1382bool
1384 // declare vehicle tags vector
1385 const std::vector<SumoXMLTag> vehicleTags = {
1387 SUMO_TAG_TRIP, SUMO_TAG_FLOW, // over edges
1388 SUMO_TAG_VEHICLE, GNE_TAG_FLOW_ROUTE, // over route
1389 GNE_TAG_VEHICLE_WITHROUTE, GNE_TAG_FLOW_WITHROUTE, // over embedded routes
1392 };
1393 for (const auto& vehicleTag : vehicleTags) {
1394 if (!checkDuplicatedDemandElement(vehicleTag, id)) {
1395 writeError(TLF("There is another % with the same ID='%'.", toString(vehicleTag), id));
1396 return true;
1397 }
1398 }
1399 return false;
1400}
1401
1402
1403bool
1404GNERouteHandler::isViaAttributeValid(const std::vector<std::string>& via) {
1405 for (const auto& edgeID : via) {
1406 if (myNet->getAttributeCarriers()->retrieveEdge(edgeID, false) == nullptr) {
1407 writeError(TLF("Via edge '%' doesn't exist.", edgeID));
1408 return false;
1409 }
1410 }
1411 return true;
1412}
1413
1414
1415bool
1417 const std::vector<SumoXMLTag> personTags = std::vector<SumoXMLTag>({SUMO_TAG_PERSON, SUMO_TAG_PERSONFLOW});
1418 for (const auto& personTag : personTags) {
1419 if (!checkDuplicatedDemandElement(personTag, id)) {
1420 writeError(TLF("There is another % with the same ID='%'.", toString(personTag), id));
1421 return true;
1422 }
1423 }
1424 return false;
1425}
1426
1427
1428bool
1430 const std::vector<SumoXMLTag> containerTags = std::vector<SumoXMLTag>({SUMO_TAG_CONTAINER, SUMO_TAG_CONTAINERFLOW});
1431 for (const auto& containerTag : containerTags) {
1432 if (!checkDuplicatedDemandElement(containerTag, id)) {
1433 writeError(TLF("There is another % with the same ID='%'.", toString(containerTag), id));
1434 return true;
1435 }
1436 }
1437 return false;
1438}
1439
1440
1441void
1442GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1443 // get pointer to net
1444 GNENet* net = originalVehicle->getNet();
1445 // check if transform after creation
1446 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1447 // declare route handler
1448 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1449 // make a copy of the vehicle parameters
1450 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1451 // obtain vClass
1452 const auto vClass = originalVehicle->getVClass();
1453 // set "yellow" as original route color
1454 RGBColor routeColor = RGBColor::YELLOW;
1455 // declare edges
1456 std::vector<GNEEdge*> routeEdges;
1457 // obtain edges depending of tag
1458 if (originalVehicle->getTagProperty().vehicleRoute()) {
1459 // get route edges
1460 routeEdges = originalVehicle->getParentDemandElements().at(1)->getParentEdges();
1461 // get original route color
1462 routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1463 } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1464 // get embedded route edges
1465 routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1466 } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1467 // calculate path using from-via-to edges
1468 routeEdges = originalVehicle->getNet()->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1469 }
1470 // declare edge IDs
1471 std::vector<std::string> edgeIDs;
1472 for (const auto& edge : routeEdges) {
1473 edgeIDs.push_back(edge->getID());
1474 }
1475 // only continue if edges are valid
1476 if (routeEdges.empty()) {
1477 // declare header
1478 const std::string header = "Problem transforming to vehicle";
1479 // declare message
1480 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1481 // write warning
1482 WRITE_DEBUG("Opened FXMessageBox " + header);
1483 // open message box
1484 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1485 // write warning if netedit is running in testing mode
1486 WRITE_DEBUG("Closed FXMessageBox " + header);
1487 } else {
1488 // begin undo-redo operation
1489 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1490 // first delete vehicle
1491 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1492 // check if new vehicle must have an embedded route
1493 if (createEmbeddedRoute) {
1494 // change tag in vehicle parameters
1495 vehicleParameters.tag = GNE_TAG_VEHICLE_WITHROUTE;
1496 // create a flow with embebbed routes
1498 CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1499 // fill parameters
1500 vehicleBaseOBject->setTag(SUMO_TAG_VEHICLE);
1501 vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1502 vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1503 // build embedded route
1504 routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1505 // delete vehicle base object
1506 delete vehicleBaseOBject;
1507 } else {
1508 // change tag in vehicle parameters
1509 vehicleParameters.tag = SUMO_TAG_VEHICLE;
1510 // generate route ID
1511 const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1512 // build route
1513 routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
1514 // set route ID in vehicle parameters
1515 vehicleParameters.routeid = routeID;
1516 // create vehicle
1517 routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
1518 }
1519 // end undo-redo operation
1520 net->getViewNet()->getUndoList()->end();
1521 // check if inspect
1522 if (inspectAfterTransform) {
1523 // get created element
1524 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1525 // inspect it
1526 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1527 }
1528 }
1529}
1530
1531
1532void
1533GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1534 // get pointer to net
1535 GNENet* net = originalVehicle->getNet();
1536 // check if transform after creation
1537 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1538 // declare route handler
1539 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1540 // obtain vehicle parameters
1541 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1542 // obtain vClass
1543 const auto vClass = originalVehicle->getVClass();
1544 // set "yellow" as original route color
1545 RGBColor routeColor = RGBColor::YELLOW;
1546 // declare edges
1547 std::vector<GNEEdge*> routeEdges;
1548 // obtain edges depending of tag
1549 if (originalVehicle->getTagProperty().vehicleRoute()) {
1550 // get route edges
1551 routeEdges = originalVehicle->getParentDemandElements().back()->getParentEdges();
1552 // get original route color
1553 routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1554 } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1555 // get embedded route edges
1556 routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1557 } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1558 // calculate path using from-via-to edges
1559 routeEdges = originalVehicle->getNet()->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1560 }
1561 // declare edge IDs
1562 std::vector<std::string> edgeIDs;
1563 for (const auto& edge : routeEdges) {
1564 edgeIDs.push_back(edge->getID());
1565 }
1566 // only continue if edges are valid
1567 if (routeEdges.empty()) {
1568 // declare header
1569 const std::string header = "Problem transforming to vehicle";
1570 // declare message
1571 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1572 // write warning
1573 WRITE_DEBUG("Opened FXMessageBox " + header);
1574 // open message box
1575 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1576 // write warning if netedit is running in testing mode
1577 WRITE_DEBUG("Closed FXMessageBox " + header);
1578 } else {
1579 // begin undo-redo operation
1580 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1581 // first delete vehicle
1582 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1583 // change depart
1584 if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
1585 // get template flow
1587 // set flow parameters
1588 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1589 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1590 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1591 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1592 // by default, number and end enabled
1593 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1594 }
1595 // check if new vehicle must have an embedded route
1596 if (createEmbeddedRoute) {
1597 // change tag in vehicle parameters
1598 vehicleParameters.tag = GNE_TAG_FLOW_WITHROUTE;
1599 // create a flow with embebbed routes
1601 CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1602 // fill parameters
1603 vehicleBaseOBject->setTag(SUMO_TAG_FLOW);
1604 vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1605 vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1606 // build embedded route
1607 routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1608 // delete vehicle base object
1609 delete vehicleBaseOBject;
1610 } else {
1611 // change tag in vehicle parameters
1612 vehicleParameters.tag = GNE_TAG_FLOW_ROUTE;
1613 // generate a new route id
1614 const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1615 // build route
1616 routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, 1.0, {});
1617 // set route ID in vehicle parameters
1618 vehicleParameters.routeid = routeID;
1619 // create vehicle
1620 routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
1621 }
1622 // end undo-redo operation
1623 net->getViewNet()->getUndoList()->end();
1624 // check if inspect
1625 if (inspectAfterTransform) {
1626 // get created element
1627 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1628 // inspect it
1629 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1630 }
1631 }
1632}
1633
1634
1635void
1637 // get pointer to net
1638 GNENet* net = originalVehicle->getNet();
1639 // check if transform after creation
1640 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1641 // declare route handler
1642 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1643 // obtain vehicle parameters
1644 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1645 // get route
1646 GNEDemandElement* route = nullptr;
1647 // declare edges
1648 std::vector<GNEEdge*> edges;
1649 // obtain edges depending of tag
1650 if (originalVehicle->getTagProperty().vehicleRoute()) {
1651 // set route
1652 route = originalVehicle->getParentDemandElements().back();
1653 // get route edges
1654 edges = route->getParentEdges();
1655 } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1656 // get embedded route edges
1657 edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1658 } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1659 // just take parent edges (from and to)
1660 edges = originalVehicle->getParentEdges();
1661 }
1662 // only continue if edges are valid
1663 if (edges.size() < 2) {
1664 // declare header
1665 const std::string header = "Problem transforming to vehicle";
1666 // declare message
1667 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1668 // write warning
1669 WRITE_DEBUG("Opened FXMessageBox " + header);
1670 // open message box
1671 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1672 // write warning if netedit is running in testing mode
1673 WRITE_DEBUG("Closed FXMessageBox " + header);
1674 } else {
1675 // begin undo-redo operation
1676 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_TRIP));
1677 // first delete vehicle
1678 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1679 // check if route has to be deleted
1680 if (route && route->getChildDemandElements().empty()) {
1681 net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1682 }
1683 // change tag in vehicle parameters
1684 vehicleParameters.tag = SUMO_TAG_TRIP;
1685 // create trip
1686 routeHandler.buildTrip(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1687 // end undo-redo operation
1688 net->getViewNet()->getUndoList()->end();
1689 // check if inspect
1690 if (inspectAfterTransform) {
1691 // get created element
1692 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1693 // inspect it
1694 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1695 }
1696 }
1697}
1698
1699
1700void
1702 // get pointer to net
1703 GNENet* net = originalVehicle->getNet();
1704 // check if transform after creation
1705 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1706 // declare route handler
1707 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1708 // obtain vehicle parameters
1709 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1710 // declare route
1711 GNEDemandElement* route = nullptr;
1712 // declare edges
1713 std::vector<GNEEdge*> edges;
1714 // obtain edges depending of tag
1715 if (originalVehicle->getTagProperty().vehicleRoute()) {
1716 // set route
1717 route = originalVehicle->getParentDemandElements().back();
1718 // get route edges
1719 edges = route->getParentEdges();
1720 } else if (originalVehicle->getTagProperty().vehicleRouteEmbedded()) {
1721 // get embedded route edges
1722 edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1723 } else if (originalVehicle->getTagProperty().vehicleEdges()) {
1724 // just take parent edges (from and to)
1725 edges = originalVehicle->getParentEdges();
1726 }
1727 // only continue if edges are valid
1728 if (edges.empty()) {
1729 // declare header
1730 const std::string header = "Problem transforming to vehicle";
1731 // declare message
1732 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1733 // write warning
1734 WRITE_DEBUG("Opened FXMessageBox " + header);
1735 // open message box
1736 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1737 // write warning if netedit is running in testing mode
1738 WRITE_DEBUG("Closed FXMessageBox " + header);
1739 } else {
1740 // begin undo-redo operation
1741 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1742 // first delete vehicle
1743 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1744 // check if route has to be deleted
1745 if (route && route->getChildDemandElements().empty()) {
1746 net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1747 }
1748 // change depart
1749 if (!GNEAttributeCarrier::getTagProperty(vehicleParameters.tag).isFlow()) {
1750 // get template flow
1752 // set flow parameters
1753 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1754 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1755 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1756 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1757 // by default, number and end enabled
1758 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1759 }
1760 // change tag in vehicle parameters
1761 vehicleParameters.tag = SUMO_TAG_FLOW;
1762 // create flow
1763 routeHandler.buildFlow(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1764 // end undo-redo operation
1765 net->getViewNet()->getUndoList()->end();
1766 // check if inspect
1767 if (inspectAfterTransform) {
1768 // get created element
1769 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1770 // inspect it
1771 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1772 }
1773 }
1774}
1775
1776
1777void
1779 // only continue if number of junctions are valid
1780 if (originalVehicle->getParentJunctions().empty()) {
1781 // declare header
1782 const std::string header = "Problem transforming to trip over junctions";
1783 // declare message
1784 const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
1785 // write warning
1786 WRITE_DEBUG("Opened FXMessageBox " + header);
1787 // open message box
1788 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1789 // write warning if netedit is running in testing mode
1790 WRITE_DEBUG("Closed FXMessageBox " + header);
1791 } else {
1792 // get pointer to net
1793 GNENet* net = originalVehicle->getNet();
1794 // check if transform after creation
1795 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1796 // declare route handler
1797 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1798 // obtain vehicle parameters
1799 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1800 // begin undo-redo operation
1801 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_JUNCTIONS));
1802 // first delete vehicle
1803 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1804 // change tag in vehicle parameters
1805 vehicleParameters.tag = GNE_TAG_TRIP_JUNCTIONS;
1806 // create trip
1807 routeHandler.buildTripJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
1808 // end undo-redo operation
1809 net->getViewNet()->getUndoList()->end();
1810 // check if inspect
1811 if (inspectAfterTransform) {
1812 // get created element
1813 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1814 // inspect it
1815 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1816 }
1817 }
1818}
1819
1820
1821void
1823 // only continue if number of junctions are valid
1824 if (originalVehicle->getParentJunctions().empty()) {
1825 // declare header
1826 const std::string header = "Problem transforming to flow over junctions";
1827 // declare message
1828 const std::string message = "Vehicle cannot be transformed. Invalid number of junctions";
1829 // write warning
1830 WRITE_DEBUG("Opened FXMessageBox " + header);
1831 // open message box
1832 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1833 // write warning if netedit is running in testing mode
1834 WRITE_DEBUG("Closed FXMessageBox " + header);
1835 } else {
1836 // get pointer to net
1837 GNENet* net = originalVehicle->getNet();
1838 // check if transform after creation
1839 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1840 // declare route handler
1841 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1842 // obtain vehicle parameters
1843 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1844 // begin undo-redo operation
1845 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_JUNCTIONS));
1846 // first delete vehicle
1847 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1848 // get template flow
1850 // set flow parameters
1851 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1852 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1853 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1854 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1855 // by default, number and end enabled
1856 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1857 // change tag in vehicle parameters
1858 vehicleParameters.tag = GNE_TAG_FLOW_JUNCTIONS;
1859 // create flow
1860 routeHandler.buildFlowJunctions(nullptr, vehicleParameters, originalVehicle->getParentJunctions().front()->getID(), originalVehicle->getParentJunctions().back()->getID());
1861 // end undo-redo operation
1862 net->getViewNet()->getUndoList()->end();
1863 // check if inspect
1864 if (inspectAfterTransform) {
1865 // get created element
1866 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1867 // inspect it
1868 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1869 }
1870 }
1871}
1872
1873
1874void
1876 // only continue if number of junctions are valid
1877 if (originalVehicle->getParentAdditionals().empty()) {
1878 // declare header
1879 const std::string header = "Problem transforming to trip over TAZs";
1880 // declare message
1881 const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
1882 // write warning
1883 WRITE_DEBUG("Opened FXMessageBox " + header);
1884 // open message box
1885 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1886 // write warning if netedit is running in testing mode
1887 WRITE_DEBUG("Closed FXMessageBox " + header);
1888 } else {
1889 // get pointer to net
1890 GNENet* net = originalVehicle->getNet();
1891 // check if transform after creation
1892 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1893 // declare route handler
1894 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1895 // obtain vehicle parameters
1896 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1897 // begin undo-redo operation
1898 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_TRIP_TAZS));
1899 // first delete vehicle
1900 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1901 // change tag in vehicle parameters
1902 vehicleParameters.tag = GNE_TAG_TRIP_TAZS;
1903 // create trip
1904 routeHandler.buildTripTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
1905 // end undo-redo operation
1906 net->getViewNet()->getUndoList()->end();
1907 // check if inspect
1908 if (inspectAfterTransform) {
1909 // get created element
1910 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1911 // inspect it
1912 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1913 }
1914 }
1915}
1916
1917
1918void
1920 // only continue if number of junctions are valid
1921 if (originalVehicle->getParentAdditionals().empty()) {
1922 // declare header
1923 const std::string header = "Problem transforming to flow over TAZs";
1924 // declare message
1925 const std::string message = "Vehicle cannot be transformed. Invalid number of TAZs";
1926 // write warning
1927 WRITE_DEBUG("Opened FXMessageBox " + header);
1928 // open message box
1929 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1930 // write warning if netedit is running in testing mode
1931 WRITE_DEBUG("Closed FXMessageBox " + header);
1932 } else {
1933 // get pointer to net
1934 GNENet* net = originalVehicle->getNet();
1935 // check if transform after creation
1936 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalVehicle);
1937 // declare route handler
1938 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1939 // obtain vehicle parameters
1940 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1941 // begin undo-redo operation
1942 net->getViewNet()->getUndoList()->begin(originalVehicle, "transform " + originalVehicle->getTagStr() + " to " + toString(GNE_TAG_FLOW_TAZS));
1943 // first delete vehicle
1944 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1945 // get template flow
1947 // set flow parameters
1948 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1949 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1950 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1951 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1952 // by default, number and end enabled
1953 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1954 // change tag in vehicle parameters
1955 vehicleParameters.tag = GNE_TAG_FLOW_TAZS;
1956 // create flow
1957 routeHandler.buildFlowTAZs(nullptr, vehicleParameters, originalVehicle->getParentAdditionals().front()->getID(), originalVehicle->getParentAdditionals().back()->getID());
1958 // end undo-redo operation
1959 net->getViewNet()->getUndoList()->end();
1960 // check if inspect
1961 if (inspectAfterTransform) {
1962 // get created element
1963 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1964 // inspect it
1965 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1966 }
1967 }
1968}
1969
1970
1971void
1973 // get pointer to net
1974 GNENet* net = originalPerson->getNet();
1975 // check if transform after creation
1976 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalPerson);
1977 // declare route handler
1978 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
1979 // obtain person parameters
1980 SUMOVehicleParameter personParameters = *originalPerson;
1981 // save ID
1982 const auto ID = personParameters.id;
1983 // set dummy ID
1984 personParameters.id = "%dummyID%";
1985 // begin undo-redo operation
1986 net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSON));
1987 // create personFlow and get it
1988 routeHandler.buildPerson(nullptr, personParameters);
1989 auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, "%dummyID%");
1990 // duplicate plans in new person
1991 for (const auto& personPlan : originalPerson->getChildDemandElements()) {
1992 routeHandler.duplicatePlan(personPlan, newPerson);
1993 }
1994 // delete original person plan
1995 net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
1996 // restore ID of new person plan
1997 newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
1998 // finish undoList
1999 net->getViewNet()->getUndoList()->end();
2000 // check if inspect
2001 if (inspectAfterTransform) {
2003 }
2004}
2005
2006
2007void
2009 // get pointer to net
2010 GNENet* net = originalPerson->getNet();
2011 // check if transform after creation
2012 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalPerson);
2013 // declare route handler
2014 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
2015 // obtain person parameters
2016 SUMOVehicleParameter personParameters = *originalPerson;
2017 // get person plans
2018 const auto personPlans = originalPerson->getChildDemandElements();
2019 // save ID
2020 const auto ID = personParameters.id;
2021 // set dummy ID
2022 personParameters.id = "%dummyID%";
2023 // begin undo-redo operation
2024 net->getViewNet()->getUndoList()->begin(originalPerson, "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSONFLOW));
2025 // create personFlow and get it
2026 routeHandler.buildPersonFlow(nullptr, personParameters);
2027 auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, "%dummyID%");
2028 // move all person plans to new person
2029 for (const auto& personPlan : personPlans) {
2030 routeHandler.duplicatePlan(personPlan, newPerson);
2031 }
2032 // delete original person plan
2033 net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2034 // restore ID of new person plan
2035 newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2036 // enable attributes
2037 newPerson->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2038 newPerson->enableAttribute(SUMO_ATTR_PERSONSPERHOUR, net->getViewNet()->getUndoList());
2039 // finish undoList
2040 net->getViewNet()->getUndoList()->end();
2041 // check if inspect
2042 if (inspectAfterTransform) {
2044 }
2045}
2046
2047
2048void
2050 // get pointer to net
2051 GNENet* net = originalContainer->getNet();
2052 // check if transform after creation
2053 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalContainer);
2054 // declare route handler
2055 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
2056 // obtain container parameters
2057 SUMOVehicleParameter containerParameters = *originalContainer;
2058 // get container plans
2059 const auto containerPlans = originalContainer->getChildDemandElements();
2060 // save ID
2061 const auto ID = containerParameters.id;
2062 // set dummy ID
2063 containerParameters.id = "%dummyID%";
2064 // begin undo-redo operation
2065 net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINER));
2066 // create containerFlow
2067 routeHandler.buildContainer(nullptr, containerParameters);
2068 // move all container plans to new container
2069 for (const auto& containerPlan : containerPlans) {
2070 containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2071 }
2072 // delete original container plan
2073 net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2074 // restore ID of new container plan
2075 auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, "%dummyID%");
2076 newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2077 // finish undoList
2078 net->getViewNet()->getUndoList()->end();
2079 // check if inspect
2080 if (inspectAfterTransform) {
2082 }
2083}
2084
2085
2086void
2088 // get pointer to net
2089 GNENet* net = originalContainer->getNet();
2090 // check if transform after creation
2091 const bool inspectAfterTransform = net->getViewNet()->getInspectedElements().isACInspected(originalContainer);
2092 // declare route handler
2093 GNERouteHandler routeHandler("", net, net->getViewNet()->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed(), false);
2094 // obtain container parameters
2095 SUMOVehicleParameter containerParameters = *originalContainer;
2096 // get container plans
2097 const auto containerPlans = originalContainer->getChildDemandElements();
2098 // save ID
2099 const auto ID = containerParameters.id;
2100 // set dummy ID
2101 containerParameters.id = "%dummyID%";
2102 // begin undo-redo operation
2103 net->getViewNet()->getUndoList()->begin(originalContainer, "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINERFLOW));
2104 // create containerFlow
2105 routeHandler.buildContainerFlow(nullptr, containerParameters);
2106 // move all container plans to new container
2107 for (const auto& containerPlan : containerPlans) {
2108 containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2109 }
2110 // delete original container plan
2111 net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2112 // restore ID of new container plan
2113 auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, "%dummyID%");
2114 newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2115 // enable attributes
2116 newContainer->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2117 newContainer->enableAttribute(SUMO_ATTR_CONTAINERSPERHOUR, net->getViewNet()->getUndoList());
2118 // finish undoList
2119 net->getViewNet()->getUndoList()->end();
2120 // check if inspect
2121 if (inspectAfterTransform) {
2123 }
2124}
2125
2126
2127bool
2129 // continue depending of element
2130 if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2131 return canReverse(element->getNet(), SVC_PEDESTRIAN, element->getParentEdges());
2132 } else if (element->getTagProperty().vehicleRoute()) {
2133 return canReverse(element->getNet(), element->getVClass(), element->getParentDemandElements().at(1)->getParentEdges());
2134 } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2135 return canReverse(element->getNet(), element->getVClass(), element->getChildDemandElements().front()->getParentEdges());
2136 } else if (element->getTagProperty().vehicleEdges()) {
2137 return canReverse(element->getNet(), element->getVClass(), element->getParentEdges());
2138 } else if (element->getTagProperty().vehicleJunctions()) {
2140 element->getParentJunctions().back(), element->getParentJunctions().front()).size() > 0);
2141 } else if (element->getTagProperty().vehicleTAZs()) {
2142 return true;
2143 } else {
2144 return false;
2145 }
2146}
2147
2148
2149bool
2150GNERouteHandler::canReverse(GNENet* net, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges) {
2151 if (edges.empty()) {
2152 return false;
2153 } else {
2154 // obtain opposite edges
2155 std::vector<GNEEdge*> reverseEdges;
2156 for (const auto& edge : edges) {
2157 const auto oppositeEdges = edge->getOppositeEdges();
2158 // stop if there isn't opposite edges for the current edge
2159 if (oppositeEdges.empty()) {
2160 return false;
2161 } else {
2162 reverseEdges.push_back(oppositeEdges.front());
2163 }
2164 }
2165 // reverse edges
2166 std::reverse(reverseEdges.begin(), reverseEdges.end());
2167 // now check if exist a path
2168 return (net->getDemandPathManager()->getPathCalculator()->calculateDijkstraPath(vClass, edges).size() > 0);
2169 }
2170}
2171
2172
2173void
2175 // get undo list
2176 auto undoList = element->getNet()->getViewNet()->getUndoList();
2177 // continue depending of element
2178 if (element->getTagProperty().vehicleRoute()) {
2179 // reverse parent route
2180 reverse(element->getParentDemandElements().at(1));
2181 } else if (element->getTagProperty().vehicleRouteEmbedded()) {
2182 // reverse embedded route
2183 reverse(element->getChildDemandElements().front());
2184 } else if (element->getTagProperty().vehicleJunctions()) {
2185 // get from to junctions
2186 const auto fromJunction = element->getAttribute(SUMO_ATTR_FROM_JUNCTION);
2187 const auto toJunction = element->getAttribute(SUMO_ATTR_TO_JUNCTION);
2188 // swap both attributes
2189 element->setAttribute(SUMO_ATTR_FROM_JUNCTION, toJunction, undoList);
2190 element->setAttribute(SUMO_ATTR_TO_JUNCTION, fromJunction, undoList);
2191 } else if (element->getTagProperty().vehicleTAZs()) {
2192 // get from to TAZs
2193 const auto fromTAZ = element->getAttribute(SUMO_ATTR_FROM_TAZ);
2194 const auto toTAZ = element->getAttribute(SUMO_ATTR_TO_TAZ);
2195 // swap both attributes
2196 element->setAttribute(SUMO_ATTR_FROM_TAZ, toTAZ, undoList);
2197 element->setAttribute(SUMO_ATTR_TO_TAZ, fromTAZ, undoList);
2198 } else {
2199 // extract and reverse opposite edges
2200 std::vector<GNEEdge*> oppositeEdges;
2201 for (const auto& edge : element->getParentEdges()) {
2202 oppositeEdges.push_back(edge->getOppositeEdges().front());
2203 }
2204 std::reverse(oppositeEdges.begin(), oppositeEdges.end());
2205 if (element->isRoute()) {
2206 element->setAttribute(SUMO_ATTR_EDGES, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2207 } else {
2208 // set from and to
2209 element->setAttribute(SUMO_ATTR_FROM, oppositeEdges.front()->getID(), undoList);
2210 element->setAttribute(SUMO_ATTR_TO, oppositeEdges.back()->getID(), undoList);
2211 // check if add via attribute
2212 oppositeEdges.erase(oppositeEdges.begin());
2213 oppositeEdges.pop_back();
2214 if (oppositeEdges.size() > 0) {
2215 element->setAttribute(SUMO_ATTR_VIA, GNEAttributeCarrier::parseIDs(oppositeEdges), undoList);
2216 }
2217 }
2218 }
2219}
2220
2221
2222void
2224 GNEDemandElement* elementCopy = nullptr;
2225 if (element->getTagProperty().getTag() == SUMO_TAG_ROUTE) {
2226 // make a copy of the route and reverse
2227 elementCopy = GNERoute::copyRoute(dynamic_cast<GNERoute*>(element));
2228 } else if (element->getTagProperty().isVehicle()) {
2229 // make a copy of the vehicle
2230 elementCopy = GNEVehicle::copyVehicle(dynamic_cast<GNEVehicle*>(element));
2231 }
2232 // reverse copied element
2233 reverse(elementCopy);
2234}
2235
2236// ===========================================================================
2237// protected
2238// ===========================================================================
2239
2241GNERouteHandler::parseJunction(const SumoXMLTag tag, const std::string& junctionID) {
2242 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(junctionID, false);
2243 // empty junctions aren't allowed. If junction is empty, write error, clear junctions and stop
2244 if (junction == nullptr) {
2245 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_JUNCTION)));
2246 }
2247 return junction;
2248}
2249
2250
2252GNERouteHandler::parseTAZ(const SumoXMLTag tag, const std::string& TAZID) {
2254 // empty TAZs aren't allowed. If TAZ is empty, write error, clear TAZs and stop
2255 if (TAZ == nullptr) {
2256 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_TAZ)));
2257 }
2258 return TAZ;
2259}
2260
2261
2262GNEEdge*
2263GNERouteHandler::parseEdge(const SumoXMLTag tag, const std::string& edgeID,
2264 const CommonXMLStructure::SumoBaseObject* sumoBaseObject,
2265 const bool firstEdge) {
2266 GNEEdge* edge = nullptr;
2267 if (edgeID.empty()) {
2268 if (sumoBaseObject->getSumoBaseObjectChildren().size() > 0) {
2269 const auto frontTag = sumoBaseObject->getSumoBaseObjectChildren().front()->getTag();
2270 const auto backTag = sumoBaseObject->getSumoBaseObjectChildren().back()->getTag();
2271 if (firstEdge && ((frontTag == SUMO_TAG_STOP) || (frontTag == SUMO_TAG_TRAIN_STOP) ||
2272 (frontTag == SUMO_TAG_CONTAINER_STOP) || (frontTag == SUMO_TAG_CHARGING_STATION) ||
2273 (frontTag == SUMO_TAG_PARKING_AREA))) {
2274 edge = parseStopEdge(sumoBaseObject->getSumoBaseObjectChildren().front());
2275 } else if (!firstEdge && ((backTag == SUMO_TAG_STOP) || (backTag == SUMO_TAG_TRAIN_STOP) ||
2276 (backTag == SUMO_TAG_CONTAINER_STOP) || (backTag == SUMO_TAG_CHARGING_STATION) ||
2277 (backTag == SUMO_TAG_PARKING_AREA))) {
2278 edge = parseStopEdge(sumoBaseObject->getSumoBaseObjectChildren().back());
2279 }
2280 }
2281 } else {
2282 edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2283 }
2284 // write info if edge doesn't exist
2285 if (edge == nullptr) {
2286 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2287 }
2288 return edge;
2289}
2290
2291
2292GNEEdge*
2294 if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_EDGE)) {
2295 return myNet->getAttributeCarriers()->retrieveEdge(sumoBaseObject->getStringAttribute(SUMO_ATTR_EDGE), false);
2296 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_LANE)) {
2297 return parseEdgeFromLaneID(sumoBaseObject->getStringAttribute(SUMO_ATTR_LANE));
2298 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_BUS_STOP)) {
2301 if (busStop != nullptr) {
2302 return busStop->getParentLanes().front()->getParentEdge();
2303 } else if (trainStop != nullptr) {
2304 return trainStop->getParentLanes().front()->getParentEdge();
2305 } else {
2306 return nullptr;
2307 }
2308 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_TRAIN_STOP)) {
2311 if (busStop != nullptr) {
2312 return busStop->getParentLanes().front()->getParentEdge();
2313 } else if (trainStop != nullptr) {
2314 return trainStop->getParentLanes().front()->getParentEdge();
2315 } else {
2316 return nullptr;
2317 }
2318 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_CONTAINER_STOP)) {
2320 if (containerStop != nullptr) {
2321 return containerStop->getParentLanes().front()->getParentEdge();
2322 } else {
2323 return nullptr;
2324 }
2325
2326 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_CHARGING_STATION)) {
2328 if (containerStop != nullptr) {
2329 return containerStop->getParentLanes().front()->getParentEdge();
2330 } else {
2331 return nullptr;
2332 }
2333
2334 } else if (sumoBaseObject->hasStringAttribute(SUMO_ATTR_PARKING_AREA)) {
2336 if (parkingArea != nullptr) {
2337 return parkingArea->getParentLanes().front()->getParentEdge();
2338 } else {
2339 return nullptr;
2340 }
2341 } else {
2342 return nullptr;
2343 }
2344}
2345
2346
2347GNEEdge*
2348GNERouteHandler::parseEdgeFromLaneID(const std::string& laneID) const {
2349 std::string edgeID = laneID;
2350 for (int i = ((int)laneID.size() - 1); (i >= 0) && (laneID[i + 1] != '_'); i--) {
2351 edgeID.pop_back();
2352 }
2353 return myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2354}
2355
2356
2357std::vector<GNEEdge*>
2358GNERouteHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
2359 std::vector<GNEEdge*> edges;
2360 for (const auto& edgeID : edgeIDs) {
2361 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2362 // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2363 if (edge == nullptr) {
2364 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2365 edges.clear();
2366 return edges;
2367 } else {
2368 edges.push_back(edge);
2369 }
2370 }
2371 return edges;
2372}
2373
2374
2376GNERouteHandler::getType(const std::string& id) const {
2378 if (type == nullptr) {
2380 } else {
2381 return type;
2382 }
2383}
2384
2385
2388 // check that sumoBaseObject has parent
2389 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2390 return nullptr;
2391 }
2392 if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSON) &&
2393 (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSONFLOW)) {
2394 return nullptr;
2395 }
2396 // try it with person
2398 // if empty, try it with personFlow
2399 if (personParent == nullptr) {
2401 } else {
2402 return personParent;
2403 }
2404}
2405
2406
2409 // check that sumoBaseObject has parent
2410 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2411 return nullptr;
2412 }
2413 if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINER) &&
2414 (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2415 return nullptr;
2416 }
2417 // try it with container
2419 // if empty, try it with containerFlow
2420 if (containerParent == nullptr) {
2422 } else {
2423 return containerParent;
2424 }
2425}
2426
2427
2428bool
2430 const std::vector<std::string>& distributionElementIDs, const std::vector<double>& probabilities,
2431 std::vector<const GNEDemandElement*>& elements) {
2432 // get distribution tag and ID
2433 std::string distributionTag = toString(sumoBaseObject->getTag());
2434 std::string distributionID = sumoBaseObject->getStringAttribute(SUMO_ATTR_ID);
2435 // first parse vType IDs
2436 for (const auto& distributionElementID : distributionElementIDs) {
2437 auto distributionElement = myNet->getAttributeCarriers()->retrieveDemandElement(distributionElementTag, distributionElementID, false);
2438 if (distributionElement) {
2439 elements.push_back(distributionElement);
2440 } else {
2441 writeError(TLF("% with id '%' doesn't exist in % '%'", toString(distributionElementTag), distributionElementID, distributionTag, distributionID));
2442 return false;
2443
2444 }
2445 }
2446 // check probabilities
2447 for (const auto& probability : probabilities) {
2448 if (probability < 0) {
2449 writeError(TLF("invalid probability % in % '%'", toString(probability), distributionTag, distributionID));
2450 return false;
2451 }
2452 }
2453 // check that number of elements and probabilities is the same
2454 if (elements.size() != probabilities.size()) {
2455 writeError(TLF("Invalid type distribution probabilities in % '%'. Must have the same number of elements", distributionTag, distributionID));
2456 return false;
2457 } else {
2458 return true;
2459 }
2460}
2461
2462
2463bool
2465 // retrieve demand element
2466 auto demandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false);
2467 // if demand exist, check if overwrite (delete)
2468 if (demandElement) {
2469 if (!myAllowUndoRedo) {
2470 // only overwrite if allow undo-redo
2471 return false;
2472 } else if (myOverwrite) {
2473 // update demand to overwrite
2474 myDemandToOverwrite = demandElement;
2475 return true;
2476 } else {
2477 // duplicated demand
2478 return false;
2479 }
2480 } else {
2481 // demand with these id doesn't exist, then all ok
2482 return true;
2483 }
2484}
2485
2486
2487void
2489 if (myDemandToOverwrite) {
2490 // remove element
2492 // reset pointer
2493 myDemandToOverwrite = nullptr;
2494 }
2495}
2496
2497
2498void
2500 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("Attribute % cannot be negative.", toString(attribute)));
2501}
2502
2503/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:306
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
const std::set< std::string > DEFAULT_VTYPES
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PEDESTRIAN
pedestrian
const long long int VEHPARS_DEPARTSPEED_SET
const int STOP_DURATION_SET
@ GIVEN
The lane is given.
const int STOP_SPEED_SET
const int STOP_UNTIL_SET
@ GIVEN
The speed is given.
const long long int VEHPARS_DEPARTLANE_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_TRIP_JUNCTIONS
a trip between junctions
@ GNE_TAG_TRIP_TAZS
a single trip definition that uses TAZs
@ GNE_TAG_WAYPOINT_PARKINGAREA
@ GNE_TAG_STOP_PARKINGAREA
stop placed over a parking area
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_WALK
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_TRANSHIP
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ GNE_TAG_STOP_BUSSTOP
stop placed over a busStop
@ SUMO_TAG_CONTAINERFLOW
@ GNE_TAG_WAYPOINT_TRAINSTOP
@ GNE_TAG_WAYPOINT_CONTAINERSTOP
@ GNE_TAG_WAYPOINT_BUSSTOP
@ SUMO_TAG_BUS_STOP
A bus stop.
@ GNE_TAG_WAYPOINT_CHARGINGSTATION
@ GNE_TAG_STOPPERSON_BUSSTOP
@ SUMO_TAG_STOP
stop for vehicles
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ GNE_TAG_FLOW_JUNCTIONS
a flow between junctions
@ GNE_TAG_STOP_CONTAINERSTOP
stop placed over a containerStop
@ GNE_TAG_STOPCONTAINER_CONTAINERSTOP
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ GNE_TAG_FLOW_TAZS
a flow between TAZs
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ GNE_TAG_VEHICLE_WITHROUTE
description of a vehicle with an embedded route
@ GNE_TAG_WAYPOINT_LANE
@ SUMO_TAG_PERSON
@ GNE_TAG_STOP_LANE
stop placed over a lane
@ GNE_TAG_STOPPERSON_TRAINSTOP
@ GNE_TAG_STOP_TRAINSTOP
stop placed over a trainStop
@ GNE_TAG_STOP_CHARGINGSTATION
stop placed over a charging station
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_LINES
@ GNE_ATTR_FROM_TRAINSTOP
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_LANE
@ GNE_ATTR_FROM_BUSSTOP
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VIA
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_TRAIN_STOP
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_TO_JUNCTION
@ GNE_ATTR_FLOWPARAMETERS
flow parameters (integer for mask end, number, etc...)
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_ACTTYPE
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_MODES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_GROUP
@ GNE_ATTR_FROM_CONTAINERSTOP
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_PROB
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_WALKFACTOR
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_PERSONSPERHOUR
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition Boundary.cpp:172
plan parameters (used for group all from-to parameters related with plans)
std::string fromJunction
from junction
std::string fromContainerStop
from containerStop
std::string fromTrainStop
from trainStop
std::vector< std::string > consecutiveEdges
consecutive edges
std::string toContainerStop
to containerStop
const SUMOVehicleParameter::Stop & getStopParameter() const
get stop parameters
SUMOTime getTimeAttribute(const SumoXMLAttr attr) const
get time attribute
bool hasBoolAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given bool attribute
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
void setTag(const SumoXMLTag tag)
set SumoBaseObject tag
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
bool hasTimeAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given time attribute
void addBoolAttribute(const SumoXMLAttr attr, const bool value)
add bool attribute into current SumoBaseObject node
SumoXMLTag getTag() const
get XML myTag
void addTimeAttribute(const SumoXMLAttr attr, const SUMOTime value)
add time attribute into current SumoBaseObject node
void addStringListAttribute(const SumoXMLAttr attr, const std::vector< std::string > &value)
add string list attribute into current SumoBaseObject node
void addDoubleAttribute(const SumoXMLAttr attr, const double value)
add double attribute into current SumoBaseObject node
bool hasDoubleAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given double attribute
bool getBoolAttribute(const SumoXMLAttr attr) const
get bool attribute
void setVehicleParameter(const SUMOVehicleParameter *vehicleParameter)
set vehicle parameters
void addStringAttribute(const SumoXMLAttr attr, const std::string &value)
add string attribute into current SumoBaseObject node
double getDoubleAttribute(const SumoXMLAttr attr) const
get double attribute
const SUMOVehicleParameter & getVehicleParameter() const
get vehicle parameters
const std::vector< std::string > & getStringListAttribute(const SumoXMLAttr attr) const
get string list attribute
bool hasStringListAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given string list attribute
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
const std::vector< SumoBaseObject * > & getSumoBaseObjectChildren() const
get SumoBaseObject children
An Element which don't belong to GNENet but has influence in the simulation.
const std::string getID() const
get ID (all Attribute Carriers have one)
const std::string & getTagStr() const
get tag assigned to this object in string format
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * getNet() const
get pointer to net
static std::string parseIDs(const std::vector< T > &ACs)
parses a list of specific Attribute Carriers into a string of IDs
void getAttributesAndValues(CommonXMLStructure::SumoBaseObject *baseObject, bool includeAll) const
get attributes and their values
void addDistributionKey(const GNEDemandElement *key, const double value, GNEUndoList *undoList)
add distribution key
virtual SUMOVehicleClass getVClass() const =0
obtain VClass related with this demand element
virtual double getAttributeDouble(SumoXMLAttr key) const =0
virtual std::string getAttribute(SumoXMLAttr key) const =0
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform demand element changes
static std::pair< SumoXMLTag, GUIIcon > getPersonTripTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the personTrip tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getContainerStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the container stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getRideTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the ride tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getPersonStopTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the person stop tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getWalkTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the walk tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTranshipTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the tranship tag and icon for the combination
static std::pair< SumoXMLTag, GUIIcon > getTransportTagIcon(const CommonXMLStructure::PlanParameters &planParameters)
get the transport tag and icon for the combination
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
void addChildElement(T *element)
add child element
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
void inspectSingleElement(GNEAttributeCarrier *AC)
Inspect a single element.
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition GNELane.h:46
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:196
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
std::string generateDemandElementID(SumoXMLTag tag) const
generate demand element id
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
void insertDemandElement(GNEDemandElement *demandElement)
Insert a demand element in container.
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition GNENet.cpp:697
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:145
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:127
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2155
bool isRoute() const
check if pathElement is a route
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges) const
calculate Dijkstra path between a list of edges (for example, from-via-to edges)
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
double getClickedPositionOverLane() const
get clicked position over lane
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
GNEPlanParents (used for group all plan parents)
void addChildElements(GNEDemandElement *element)
add the given element in the element as child
bool checkIntegrity(SumoXMLTag planTag, const GNEDemandElement *parent, const CommonXMLStructure::PlanParameters &planParameters) const
check integrity between planParameters and GNE elements
void incRef(const std::string &debugMsg="")
Increase reference.
Builds trigger objects for GNENet (busStops, chargingStations, detectors, etc..)
void buildTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeID)
build trip
void buildPersonStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build person stop
bool isContainerIdDuplicated(const std::string &id)
check if there is already a container (Container or ContainerFlow) with the given ID
GNEEdge * parseStopEdge(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
parse stop edge
const bool myOverwrite
check if overwrite
bool isVehicleIdDuplicated(const std::string &id)
check if there is already a vehicle (Vehicle, Trip, Flow or Flow) with the given ID
void buildContainerFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &containerFlowParameters)
build container flow
static void addReverse(GNEDemandElement *element)
add reverse for given demand element
bool checkDuplicatedDemandElement(const SumoXMLTag tag, const std::string &id)
check if given ID correspond to a duplicated demand element
bool buildPersonPlan(const GNEDemandElement *planTemplate, GNEDemandElement *personParent, GNEAttributesCreator *personPlanAttributes, GNEPlanCreator *planCreator, const bool centerAfterCreation)
build person plan
CommonXMLStructure::SumoBaseObject * myPlanObject
pointer for person and container plans
GNEDemandElement * getPersonParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get person parent
GNEJunction * parseJunction(const SumoXMLTag tag, const std::string &junctionID)
parse junction
void writeErrorInvalidNegativeValue(const SumoXMLTag tag, const SumoXMLAttr attribute)
write error "invalid negative element"
const bool myAllowUndoRedo
allow undo/redo
void overwriteDemandElement()
remove overwritten demand element
GNEEdge * parseEdgeFromLaneID(const std::string &laneID) const
parse edge from lane ID
void buildPerson(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personParameters)
build person
void buildPersonTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &types, const std::vector< std::string > &modes, const std::vector< std::string > &lines, const double walkFactor, const std::string &group)
build person trip
static void transformToRouteFlow(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform routeFlow over an existent route
GNENet * myNet
pointer to GNENet
void duplicatePlan(const GNEDemandElement *originalPlan, GNEDemandElement *newParent)
duplicate given plan in new parent
void buildFlowTAZs(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromTAZID, const std::string &toTAZID)
build flow over junctions
bool isPersonIdDuplicated(const std::string &id)
check if there is already a person (Person or PersonFlow) with the given ID
static void transformToContainerFlow(GNEContainer *originalContainer)
transform routeFlow over an existent route
void buildVehicleOverRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters)
build a vehicle over an existent route
void buildWalk(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const double speed, const SUMOTime duration)
build walk
GNEEdge * parseEdge(const SumoXMLTag tag, const std::string &edgeID, const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const bool firstEdge)
parse edge
static void transformToFlow(GNEVehicle *originalVehicle)
transform to flow
void buildTripTAZs(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromTAZID, const std::string &toTAZID)
build trip over TAZs
void buildFlowOverRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters)
build a flow over an existent route
void buildTripJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build trip over junctions
void buildContainerStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double endPos, const SUMOTime duration, const SUMOTime until, const std::string &actType, const bool friendlyPos, const int parameterSet)
build container stop
void buildVTypeDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const int deterministic, const std::vector< std::string > &vTypeIDs, const std::vector< double > &probabilities)
build vType distribution
void buildFlowJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build flow over junctions
static bool canReverse(const GNEDemandElement *element)
reverse functions
bool isViaAttributeValid(const std::vector< std::string > &via)
check if via attribute is valid
void buildVType(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVTypeParameter &vTypeParameter)
build vType
static void transformToTrip(GNEVehicle *originalVehicle)
transform to trip
void buildRouteDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::vector< std::string > &routeIDs, const std::vector< double > &probabilities)
build route distribution
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
void buildRide(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &lines, const std::string &group)
build ride
void buildFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeIDs)
build flow
bool buildContainerPlan(const GNEDemandElement *planTemplate, GNEDemandElement *containerParent, GNEAttributesCreator *containerPlanAttributes, GNEPlanCreator *planCreator, const bool centerAfterCreation)
build container plan
GNEAdditional * parseTAZ(const SumoXMLTag tag, const std::string &TAZID)
parse TAZ
GNEDemandElement * getType(const std::string &id) const
get type (Either type o typeDistribution)
virtual ~GNERouteHandler()
Destructor.
void buildTranship(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPosition, const double departPosition, const double speed, const SUMOTime duration)
build tranship
void buildEmbeddedRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::vector< std::string > &edgeIDs, const RGBColor &color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map &routeParameters)
build embedded route
void buildPersonFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personFlowParameters)
build person flow
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::vector< std::string > &edgeIDs)
parse edges
void buildTransport(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const double arrivalPos, const std::vector< std::string > &lines, const std::string &group)
build transport
void buildStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const CommonXMLStructure::PlanParameters &planParameters, const SUMOVehicleParameter::Stop &stopParameters)
build stop
GNEDemandElement * getContainerParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get container parent
static void reverse(GNEDemandElement *element)
reverse given demand element
static void transformToFlowJunctions(GNEVehicle *originalVehicle)
transform to flow over junctions
static void transformToTripJunctions(GNEVehicle *originalVehicle)
transform to trip over junctions
static void transformToContainer(GNEContainer *originalContainer)
transform container functions
void buildContainer(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &containerParameters)
build container
static void transformToPersonFlow(GNEPerson *originalPerson)
transform routeFlow over an existent route
bool getDistributionElements(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, SumoXMLTag distributionElementTag, const std::vector< std::string > &distributionElementIDs, const std::vector< double > &probabilities, std::vector< const GNEDemandElement * > &elements)
get distribution elements
void buildRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, SUMOVehicleClass vClass, const std::vector< std::string > &edgeIDs, const RGBColor &color, const int repeat, const SUMOTime cycleTime, const double probability, const Parameterised::Map &routeParameters)
build route
GNEDemandElement * myDemandToOverwrite
demand to overwrite (using undo-redo
static void transformToFlowTAZs(GNEVehicle *originalVehicle)
transform to flow over TAZs
GNERouteHandler(const std::string &file, GNENet *net, const bool allowUndoRedo, const bool overwrite)
Constructor.
static void transformToVehicle(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform vehicle functions
static void transformToTripTAZs(GNEVehicle *originalVehicle)
transform to trip over TAZs
static GNEDemandElement * copyRoute(const GNERoute *originalRoute)
create a copy of the given route
Definition GNERoute.cpp:724
bool isPlanTransport() const
return true if tag correspond to a transport
bool isContainer() const
return true if tag correspond to a container element
bool isFlow() const
return true if tag correspond to a flow element
bool isVehicle() const
return true if tag correspond to a vehicle element
bool vehicleJunctions() const
return true if tag correspond to a vehicle placed over from-to junctions
bool isPlanStopContainer() const
return true if tag correspond to a container stop plan
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool vehicleRouteEmbedded() const
return true if tag correspond to a vehicle placed over an embedded route
bool isPlanPersonTrip() const
return true if tag correspond to a person trip plan
bool vehicleEdges() const
return true if tag correspond to a vehicle placed over from-to edges
bool isPlanRide() const
return true if tag correspond to a ride plan
bool isPlanStopPerson() const
return true if tag correspond to a person stop plan
bool isPerson() const
return true if tag correspond to a person element
bool vehicleTAZs() const
return true if tag correspond to a vehicle placed over from-to TAZs
bool vehicleRoute() const
plan parents
bool isPlanWalk() const
return true if tag correspond to a walk plan
bool isPlanTranship() const
return true if tag correspond to a tranship
GNEAttributeCarrier * getTemplateAC(SumoXMLTag ACTag) const
get templateAC
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
static void overwriteVType(GNEDemandElement *vType, const SUMOVTypeParameter newVTypeParameter, GNEUndoList *undoList)
overwrite all values of GNEVType with a SUMOVTypeParameter
Definition GNEVType.cpp:964
GNETagSelector * getVehicleTagSelector() const
get vehicle tag selector (needed for transform vehicles)
SUMOVehicleClass getVClass() const
obtain VClass related with this demand element
static GNEDemandElement * copyVehicle(const GNEVehicle *originalVehicle)
create a copy of the given vehicle
bool isACInspected(GNEAttributeCarrier *AC) const
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
GNEVehicleFrame * getVehicleFrame() const
get frame for DEMAND_VEHICLE
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
Boundary getVisibleBoundary() const
get visible boundary
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
std::map< std::string, std::string > Map
parameters map
static const RGBColor YELLOW
Definition RGBColor.h:188
static const RGBColor INVISIBLE
Definition RGBColor.h:195
void writeError(const std::string &error)
write error and enable error creating element
Structure representing possible vehicle parameter.
std::string id
The vehicle type's id.
Definition of vehicle stop (position and duration)
std::string edge
The edge to stop at.
std::string lane
The lane to stop at.
bool friendlyPos
enable or disable friendly position (used by netedit)
double speed
the speed at which this stop counts as reached (waypoint mode)
std::string parkingarea
(Optional) parking area if one is assigned to the stop
std::string chargingStation
(Optional) charging station if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
SUMOTime until
The time at which the vehicle may continue its journey.
std::string actType
act Type (only used by Persons) (used by netedit)
double endPos
The stopping position end.
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string containerstop
(Optional) container stop if one is assigned to the stop
SUMOTime duration
The stopping duration.
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double departSpeed
(optional) The initial speed of the vehicle
SumoXMLTag tag
The vehicle tag.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
bool wasSet(long long int what) const
Returns whether the given parameter was set.
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.