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-2023 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 <config.h>
21#include <netedit/GNENet.h>
22#include <netedit/GNEUndoList.h>
23#include <netedit/GNEViewNet.h>
28
29#include "GNEContainer.h"
30#include "GNEPerson.h"
31#include "GNEPersonTrip.h"
32#include "GNERide.h"
33#include "GNERoute.h"
34#include "GNERouteHandler.h"
35#include "GNEStop.h"
36#include "GNETranship.h"
37#include "GNETransport.h"
38#include "GNEVehicle.h"
39#include "GNEVType.h"
41#include "GNEWalk.h"
42
43
44// ===========================================================================
45// member method definitions
46// ===========================================================================
47
48GNERouteHandler::GNERouteHandler(const std::string& file, GNENet* net, const bool allowUndoRedo, const bool overwrite) :
49 RouteHandler(file, false),
50 myNet(net),
51 myPlanObject(new CommonXMLStructure::SumoBaseObject(nullptr)),
52 myAllowUndoRedo(allowUndoRedo),
53 myOverwrite(overwrite) {
54}
55
56
60
61
62void
64 // check if loaded type is a default type
65 if (DEFAULT_VTYPES.count(vTypeParameter.id) > 0) {
66 // overwrite default vehicle type
68 } else if (!checkDuplicatedDemandElement(SUMO_TAG_VTYPE, vTypeParameter.id)) {
69 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE), vTypeParameter.id));
70 } else {
71 // create vType/pType using myCurrentVType
72 GNEDemandElement* vType = new GNEVType(myNet, vTypeParameter);
73 if (myAllowUndoRedo) {
74 myNet->getViewNet()->getUndoList()->begin(GUIIcon::VTYPE, TL("add ") + vType->getTagStr() + " '" + vTypeParameter.id + "'");
76 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vType, true), true);
78 } else {
80 vType->incRef("buildVType");
81 }
82 }
83}
84
85
86void
88 const int deterministic, const std::vector<std::string>& vTypes) {
89 // first check conditions
91 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_VTYPE)));
92 } else if (vTypes.empty() && sumoBaseObject->getSumoBaseObjectChildren().empty()) {
94 } else {
95 bool checkVTypesOK = true;
96 // check vTypes
97 for (const auto& vType : vTypes) {
98 if (myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, vType, false) == nullptr) {
99 writeError(TLF("% with id '%' doesn't exist in % '%'", toString(SUMO_TAG_VTYPE), vType, toString(SUMO_TAG_VTYPE_DISTRIBUTION), id));
100 checkVTypesOK = false;
101 }
102 }
103 // now check childrens
104 for (const auto& child : sumoBaseObject->getSumoBaseObjectChildren()) {
105 if (child->hasStringAttribute(SUMO_ATTR_ID) == false) {
106 writeError(TLF("Invalid definition for % in % '%'", toString(SUMO_TAG_VTYPE), toString(SUMO_TAG_VTYPE_DISTRIBUTION), id));
107 checkVTypesOK = false;
108 } else if (myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, child->getStringAttribute(SUMO_ATTR_ID), false) != nullptr) {
109 writeError(TLF("% with id '%' cannot be created in % '%'", toString(SUMO_TAG_VTYPE), child->getStringAttribute(SUMO_ATTR_ID), toString(SUMO_TAG_VTYPE_DISTRIBUTION), id));
110 checkVTypesOK = false;
111 }
112 }
113 // if all ok, then create vTypeDistribution
114 if (checkVTypesOK) {
115 GNEVTypeDistribution* vTypeDistribution = new GNEVTypeDistribution(myNet, id, deterministic);
116 if (myAllowUndoRedo) {
117 myNet->getViewNet()->getUndoList()->begin(GUIIcon::VTYPEDISTRIBUTION, TL("add ") + vTypeDistribution->getTagStr() + " '" + id + "'");
119 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vTypeDistribution, true), true);
120 // iterate over all children and set attribute
121 for (const auto &typeID : vTypes) {
123 }
125 } else {
126 myNet->getAttributeCarriers()->insertDemandElement(vTypeDistribution);
127 vTypeDistribution->incRef("buildVType");
128
129 /* FALTA */
130
131 }
132 }
133 }
134}
135
136
137void
138GNERouteHandler::buildRoute(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, SUMOVehicleClass vClass,
139 const std::vector<std::string>& edgeIDs, const RGBColor& color, const int repeat, const SUMOTime cycleTime,
140 const Parameterised::Map& routeParameters) {
141 // parse edges
142 const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
143 // check conditions
145 writeError(TLF("There is another % with the same ID='%'.", toString(SUMO_TAG_ROUTE), id));
146 } else if (edges.size() > 0) {
147 // create GNERoute
148 GNEDemandElement* route = new GNERoute(myNet, id, vClass, edges, color, repeat, cycleTime, routeParameters);
149 if (myAllowUndoRedo) {
150 myNet->getViewNet()->getUndoList()->begin(GUIIcon::ROUTE, TL("add ") + route->getTagStr() + " '" + id + "'");
152 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
154 } else {
156 for (const auto& edge : edges) {
157 edge->addChildElement(route);
158 }
159 route->incRef("buildRoute");
160 }
161 }
162}
163
164
165void
166GNERouteHandler::buildEmbeddedRoute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::vector<std::string>& edgeIDs,
167 const RGBColor& color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map& routeParameters) {
168 // first create vehicle/flow
169 const SUMOVehicleParameter& vehicleParameters = sumoBaseObject->getParentSumoBaseObject()->getVehicleParameter();
170 const SumoXMLTag vehicleTag = (sumoBaseObject->getParentSumoBaseObject()->getTag() == SUMO_TAG_VEHICLE) ? GNE_TAG_VEHICLE_WITHROUTE :
172 sumoBaseObject->getParentSumoBaseObject()->getTag();
173 // parse route edges
174 const auto edges = parseEdges(SUMO_TAG_ROUTE, edgeIDs);
175 // check if ID is duplicated
176 if ((edges.size() > 0) && !isVehicleIdDuplicated(vehicleParameters.id)) {
177 // obtain routes and vtypes
179 // try to parse type distribution
180 if (type == nullptr) {
182 }
183 if (type == nullptr) {
184 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
185 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)edges.front()->getLanes().size() < vehicleParameters.departLane)) {
186 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
187 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
188 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)));
189 } else {
190 // create vehicle using vehicleParameters
191 GNEDemandElement* vehicle = new GNEVehicle(vehicleTag, myNet, type, vehicleParameters);
192 // create embedded route
193 GNEDemandElement* route = new GNERoute(myNet, vehicle, edges, color, repeat, cycleTime, routeParameters);
194 if (myAllowUndoRedo) {
195 myNet->getViewNet()->getUndoList()->begin(GUIIcon::ROUTE, TL("add ") + route->getTagStr() + " in '" + vehicle->getID() + "'");
197 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
198 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(route, true), true);
200 } else {
203 type->addChildElement(vehicle);
204 vehicle->addChildElement(route);
205 for (const auto& edge : edges) {
206 edge->addChildElement(route);
207 }
208 vehicle->incRef("buildEmbeddedRoute");
209 route->incRef("buildEmbeddedRoute");
210 }
211 // compute path
212 vehicle->computePathElement();
213 }
214 }
215}
216
217
218void
219GNERouteHandler::buildRouteDistribution(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& /*id*/) {
220 // unsupported
221 writeError(TL("netedit doesn't support route distributions"));
222}
223
224
225void
227 // first check if ID is duplicated
228 if (!isVehicleIdDuplicated(vehicleParameters.id)) {
229 // obtain routes and vtypes
232 // try to parse type distribution
233 if (type == nullptr) {
235 }
236 if (type == nullptr) {
237 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
238 } else if (route == nullptr) {
239 writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
240 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
241 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
242 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
243 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)));
244 } else {
245 // create vehicle using vehicleParameters
246 GNEDemandElement* vehicle = new GNEVehicle(SUMO_TAG_VEHICLE, myNet, type, route, vehicleParameters);
247 if (myAllowUndoRedo) {
248 myNet->getViewNet()->getUndoList()->begin(vehicle->getTagProperty().getGUIIcon(), TL("add ") + vehicle->getTagStr() + " '" + vehicleParameters.id + "'");
250 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(vehicle, true), true);
252 } else {
254 // set vehicle as child of type and Route
255 type->addChildElement(vehicle);
256 route->addChildElement(vehicle);
257 vehicle->incRef("buildVehicleOverRoute");
258 }
259 // compute path
260 vehicle->computePathElement();
261 }
262 }
263}
264
265
266void
268 // first check if ID is duplicated
269 if (!isVehicleIdDuplicated(vehicleParameters.id)) {
270 // obtain routes and vtypes
273 // try to parse type distribution
274 if (type == nullptr) {
276 }
277 if (type == nullptr) {
278 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
279 } else if (route == nullptr) {
280 writeError(TLF("Invalid route '%' used in % '%'.", vehicleParameters.routeid, toString(vehicleParameters.tag), vehicleParameters.id));
281 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)route->getParentEdges().front()->getLanes().size() < vehicleParameters.departLane)) {
282 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
283 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
284 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)));
285 } else {
286 // create flow or trips using vehicleParameters
287 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_ROUTE, myNet, type, route, vehicleParameters);
288 if (myAllowUndoRedo) {
289 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
291 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
293 } else {
295 // set flow as child of type and Route
296 type->addChildElement(flow);
297 route->addChildElement(flow);
298 flow->incRef("buildFlowOverRoute");
299 }
300 // compute path
301 flow->computePathElement();
302 }
303 }
304}
305
306
307void
309 const std::string& fromEdgeID, const std::string& toEdgeID) {
310 // parse edges
311 const auto fromEdge = parseEdge(SUMO_TAG_TRIP, fromEdgeID);
312 const auto toEdge = parseEdge(SUMO_TAG_TRIP, toEdgeID);
313 // set via attribute
314 if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
315 vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
316 }
317 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
318 if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
319 // obtain vtypes
321 // try to parse type distribution
322 if (type == nullptr) {
324 }
325 if (type == nullptr) {
326 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
327 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
328 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
329 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
330 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)));
331 } else {
332 // create trip or flow using tripParameters
333 GNEDemandElement* trip = new GNEVehicle(SUMO_TAG_TRIP, myNet, type, fromEdge, toEdge, vehicleParameters);
334 if (myAllowUndoRedo) {
335 myNet->getViewNet()->getUndoList()->begin(trip->getTagProperty().getGUIIcon(), TL("add ") + trip->getTagStr() + " '" + vehicleParameters.id + "'");
337 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(trip, true), true);
339 } else {
341 // set vehicle as child of type
342 type->addChildElement(trip);
343 trip->incRef("buildTrip");
344 // add reference in all edges
345 fromEdge->addChildElement(trip);
346 toEdge->addChildElement(trip);
347 }
348 // compute path
349 trip->computePathElement();
350 }
351 }
352}
353
354
355void
357 const std::string& fromJunctionID, const std::string& toJunctionID) {
358 // parse junctions
359 const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
360 const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
361 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
362 if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
363 // obtain vtypes
365 // try to parse type distribution
366 if (type == nullptr) {
368 }
369 if (type == nullptr) {
370 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
371 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
372 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
373 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
374 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)));
375 } else {
376 // create trip using vehicleParameters
377 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
378 if (myAllowUndoRedo) {
379 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
381 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
383 } else {
385 // set vehicle as child of type
386 type->addChildElement(flow);
387 flow->incRef("buildFlow");
388 // add reference in all junctions
389 fromJunction->addChildElement(flow);
390 toJunction->addChildElement(flow);
391 }
392 // compute path
393 flow->computePathElement();
394 }
395 }
396}
397
398
399void
401 const std::string& fromTAZID, const std::string& toTAZID) {
402 // parse TAZs
403 const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
404 const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
405 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
406 if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
407 // obtain vtypes
409 // try to parse type distribution
410 if (type == nullptr) {
412 }
413 if (type == nullptr) {
414 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
415 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
416 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
417 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
418 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)));
419 } else {
420 // create trip using vehicleParameters
421 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_TRIP_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
422 if (myAllowUndoRedo) {
423 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
425 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
427 } else {
429 // set vehicle as child of type
430 type->addChildElement(flow);
431 flow->incRef("buildFlow");
432 // add reference in all TAZs
433 fromTAZ->addChildElement(flow);
434 toTAZ->addChildElement(flow);
435 }
436 // compute path
437 flow->computePathElement();
438 }
439 }
440}
441
442
443void
445 const std::string& fromEdgeID, const std::string& toEdgeID) {
446 // parse edges
447 const auto fromEdge = parseEdge(SUMO_TAG_FLOW, fromEdgeID);
448 const auto toEdge = parseEdge(SUMO_TAG_FLOW, toEdgeID);
449 // set via attribute
450 if (sumoBaseObject && sumoBaseObject->hasStringListAttribute(SUMO_ATTR_VIA)) {
451 vehicleParameters.via = sumoBaseObject->getStringListAttribute(SUMO_ATTR_VIA);
452 }
453 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
454 if (fromEdge && toEdge && !isVehicleIdDuplicated(vehicleParameters.id) && isViaAttributeValid(vehicleParameters.via)) {
455 // obtain vtypes
457 // try to parse type distribution
458 if (type == nullptr) {
460 }
461 if (type == nullptr) {
462 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
463 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && (vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN) && ((int)fromEdge->getLanes().size() < vehicleParameters.departLane)) {
464 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
465 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
466 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)));
467 } else {
468 // create trip or flow using tripParameters
469 GNEDemandElement* flow = new GNEVehicle(SUMO_TAG_FLOW, myNet, type, fromEdge, toEdge, vehicleParameters);
470 if (myAllowUndoRedo) {
471 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
473 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
475 } else {
477 // set vehicle as child of type
478 type->addChildElement(flow);
479 flow->incRef("buildFlow");
480 // add reference in all edges
481 fromEdge->addChildElement(flow);
482 toEdge->addChildElement(flow);
483 }
484 // compute path
485 flow->computePathElement();
486 }
487 }
488}
489
490
491void
493 const std::string& fromJunctionID, const std::string& toJunctionID) {
494 // parse junctions
495 const auto fromJunction = parseJunction(SUMO_TAG_TRIP, fromJunctionID);
496 const auto toJunction = parseJunction(SUMO_TAG_TRIP, toJunctionID);
497 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
498 if (fromJunction && toJunction && !isVehicleIdDuplicated(vehicleParameters.id)) {
499 // obtain vtypes
501 // try to parse type distribution
502 if (type == nullptr) {
504 }
505 if (type == nullptr) {
506 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
507 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
508 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
509 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
510 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)));
511 } else {
512 // create flow using vehicleParameters
513 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_JUNCTIONS, myNet, type, fromJunction, toJunction, vehicleParameters);
514 if (myAllowUndoRedo) {
515 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
517 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
519 } else {
521 // set vehicle as child of type
522 type->addChildElement(flow);
523 flow->incRef("buildFlow");
524 // add reference in all junctions
525 fromJunction->addChildElement(flow);
526 toJunction->addChildElement(flow);
527 }
528 // compute path
529 flow->computePathElement();
530 }
531 }
532}
533
534
535void
537 const std::string& fromTAZID, const std::string& toTAZID) {
538 // parse TAZs
539 const auto fromTAZ = parseTAZ(SUMO_TAG_TRIP, fromTAZID);
540 const auto toTAZ = parseTAZ(SUMO_TAG_TRIP, toTAZID);
541 // check if exist another vehicle with the same ID (note: Vehicles, Flows and Trips share namespace)
542 if (fromTAZ && toTAZ && !isVehicleIdDuplicated(vehicleParameters.id)) {
543 // obtain vtypes
545 // try to parse type distribution
546 if (type == nullptr) {
548 }
549 if (type == nullptr) {
550 writeError(TLF("Invalid vehicle type '%' used in % '%'.", vehicleParameters.vtypeid, toString(vehicleParameters.tag), vehicleParameters.id));
551 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTLANE_SET) && ((vehicleParameters.departLaneProcedure == DepartLaneDefinition::GIVEN)) && (vehicleParameters.departLane > 0)) {
552 writeError(TLF("Invalid % used in % '%'. % is greater than number of lanes", toString(SUMO_ATTR_DEPARTLANE), toString(vehicleParameters.tag), vehicleParameters.id, toString(vehicleParameters.departLane)));
553 } else if (vehicleParameters.wasSet(VEHPARS_DEPARTSPEED_SET) && (vehicleParameters.departSpeedProcedure == DepartSpeedDefinition::GIVEN) && (type->getAttributeDouble(SUMO_ATTR_MAXSPEED) < vehicleParameters.departSpeed)) {
554 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)));
555 } else {
556 // create flow using vehicleParameters
557 GNEDemandElement* flow = new GNEVehicle(GNE_TAG_FLOW_TAZS, myNet, type, fromTAZ, toTAZ, vehicleParameters);
558 if (myAllowUndoRedo) {
559 myNet->getViewNet()->getUndoList()->begin(flow->getTagProperty().getGUIIcon(), TL("add ") + flow->getTagStr() + " '" + vehicleParameters.id + "'");
561 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(flow, true), true);
563 } else {
565 // set vehicle as child of type
566 type->addChildElement(flow);
567 flow->incRef("buildFlow");
568 // add reference in all TAZs
569 fromTAZ->addChildElement(flow);
570 toTAZ->addChildElement(flow);
571 }
572 // compute path
573 flow->computePathElement();
574 }
575 }
576}
577
578
579void
581 // first check if ID is duplicated
582 if (!isPersonIdDuplicated(personParameters.id)) {
583 // obtain type
585 // try to parse type distribution
586 if (type == nullptr) {
588 }
589 if (type == nullptr) {
590 writeError(TLF("Invalid vehicle type '%' used in % '%'.", personParameters.vtypeid, toString(personParameters.tag), personParameters.id));
591 } else {
592 // create person using personParameters
593 GNEDemandElement* person = new GNEPerson(SUMO_TAG_PERSON, myNet, type, personParameters);
594 if (myAllowUndoRedo) {
595 myNet->getViewNet()->getUndoList()->begin(person->getTagProperty().getGUIIcon(), TL("add ") + person->getTagStr() + " '" + personParameters.id + "'");
597 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(person, true), true);
599 } else {
601 // set person as child of type
602 type->addChildElement(person);
603 person->incRef("buildPerson");
604 }
605 }
606 }
607}
608
609
610void
611GNERouteHandler::buildPersonFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& personFlowParameters) {
612 // first check if ID is duplicated
613 if (!isPersonIdDuplicated(personFlowParameters.id)) {
614 // obtain type
616 // try to parse type distribution
617 if (type == nullptr) {
619 }
620 if (type == nullptr) {
621 writeError(TLF("Invalid vehicle type '%' used in % '%'.", personFlowParameters.vtypeid, toString(personFlowParameters.tag), personFlowParameters.id));
622 } else {
623 // create personFlow using personFlowParameters
624 GNEDemandElement* personFlow = new GNEPerson(SUMO_TAG_PERSONFLOW, myNet, type, personFlowParameters);
625 if (myAllowUndoRedo) {
626 myNet->getViewNet()->getUndoList()->begin(personFlow->getTagProperty().getGUIIcon(), TL("add ") + personFlow->getTagStr() + " '" + personFlowParameters.id + "'");
628 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personFlow, true), true);
630 } else {
632 // set personFlow as child of type
633 type->addChildElement(personFlow);
634 personFlow->incRef("buildPersonFlow");
635 }
636 }
637 }
638}
639
640
641void
642GNERouteHandler::buildPersonTrip(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& toEdgeID,
643 const std::string& fromJunctionID, const std::string& toJunctionID, const std::string& toBusStopID, const std::string& toTrainStopID,
644 double arrivalPos, const std::vector<std::string>& types, const std::vector<std::string>& modes, const std::vector<std::string>& lines) {
645 // get previous plan edge
646 const auto previousEdge = getPreviousPlanEdge(true, sumoBaseObject);
647 // parse parents
648 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
649 GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
650 GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
651 GNEJunction* fromJunction = myNet->getAttributeCarriers()->retrieveJunction(fromJunctionID, false);
652 GNEJunction* toJunction = myNet->getAttributeCarriers()->retrieveJunction(toJunctionID, false);
654 GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
655 // chek if we're parsing the train stop as a busStop
656 if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
657 toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
658 toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
659 }
660 // check from edge
661 if ((fromEdge == nullptr) && previousEdge) {
662 fromEdge = previousEdge;
663 }
664 // check from junction
665 if (fromJunction == nullptr) {
666 if (previousEdge) {
667 fromJunction = previousEdge->getToJunction();
668 } else {
669 fromJunction = getPreviousPlanJunction(true, sumoBaseObject);
670 }
671 }
672 // check conditions
673 if (personParent) {
674 if (fromEdge && toEdge) {
675 // create personTrip from->to (edges)
676 GNEDemandElement* personTrip = new GNEPersonTrip(myNet, personParent, fromEdge, toEdge, arrivalPos, types, modes, lines);
677 if (myAllowUndoRedo) {
678 myNet->getViewNet()->getUndoList()->begin(personTrip->getTagProperty().getGUIIcon(), TL("add ") + personTrip->getTagStr() + " in '" + personParent->getID() + "'");
680 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
682 } else {
684 // set child references
685 personParent->addChildElement(personTrip);
686 fromEdge->addChildElement(personTrip);
687 toEdge->addChildElement(personTrip);
688 personTrip->incRef("buildPersonTripFromTo");
689 }
690 } else if (fromEdge && toBusStop) {
691 // create personTrip from->busStop
692 GNEDemandElement* personTrip = new GNEPersonTrip(false, myNet, personParent, fromEdge, toBusStop, arrivalPos, types, modes, lines);
693 if (myAllowUndoRedo) {
694 myNet->getViewNet()->getUndoList()->begin(personTrip->getTagProperty().getGUIIcon(), TL("add ") + personTrip->getTagStr() + " in '" + personParent->getID() + "'");
696 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
698 } else {
700 // set child references
701 personParent->addChildElement(personTrip);
702 fromEdge->addChildElement(personTrip);
703 toBusStop->addChildElement(personTrip);
704 personTrip->incRef("buildPersonTripFromBusStop");
705 }
706 } else if (fromEdge && toTrainStop) {
707 // create personTrip from->trainStop
708 GNEDemandElement* personTrip = new GNEPersonTrip(true, myNet, personParent, fromEdge, toTrainStop, arrivalPos, types, modes, lines);
709 if (myAllowUndoRedo) {
710 myNet->getViewNet()->getUndoList()->begin(personTrip->getTagProperty().getGUIIcon(), TL("add ") + personTrip->getTagStr() + " in '" + personParent->getID() + "'");
712 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
714 } else {
716 // set child references
717 personParent->addChildElement(personTrip);
718 fromEdge->addChildElement(personTrip);
719 toTrainStop->addChildElement(personTrip);
720 personTrip->incRef("buildPersonTripFromTrainStop");
721 }
722 } else if (fromJunction && toJunction) {
723 // create personTrip from->to (junctions)
724 GNEDemandElement* personTrip = new GNEPersonTrip(myNet, personParent, fromJunction, toJunction, arrivalPos, types, modes, lines);
725 if (myAllowUndoRedo) {
726 myNet->getViewNet()->getUndoList()->begin(personTrip->getTagProperty().getGUIIcon(), TL("add ") + personTrip->getTagStr() + " in '" + personParent->getID() + "'");
728 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(personTrip, true), true);
730 } else {
732 // set child references
733 personParent->addChildElement(personTrip);
734 fromJunction->addChildElement(personTrip);
735 toJunction->addChildElement(personTrip);
736 personTrip->incRef("buildPersonTripFromTo");
737 }
738 }
739 }
740}
741
742
743void
744GNERouteHandler::buildWalk(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& toEdgeID,
745 const std::string& fromJunctionID, const std::string& toJunctionID, const std::string& toBusStopID, const std::string& toTrainStopID,
746 const std::vector<std::string>& edgeIDs, const std::string& routeID, double arrivalPos) {
747 // get previous plan edge
748 const auto previousEdge = getPreviousPlanEdge(true, sumoBaseObject);
749 // parse parents
750 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
751 GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
752 GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
753 GNEJunction* fromJunction = myNet->getAttributeCarriers()->retrieveJunction(fromJunctionID, false);
754 GNEJunction* toJunction = myNet->getAttributeCarriers()->retrieveJunction(toJunctionID, false);
756 GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
757 // chek if we're parsing the train stop as a busStop
758 if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
759 toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
760 toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
761 }
763 std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_WALK, edgeIDs);
764 // avoid consecutive duplicated edges
765 edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
766 // check from edge
767 if ((fromEdge == nullptr) && previousEdge) {
768 fromEdge = previousEdge;
769 }
770 // check from junction
771 if (fromJunction == nullptr) {
772 if (previousEdge) {
773 fromJunction = previousEdge->getToJunction();
774 } else {
775 fromJunction = getPreviousPlanJunction(true, sumoBaseObject);
776 }
777 }
778 // check conditions
779 if (personParent) {
780 if (edges.size() > 0) {
781 // create walk edges
782 GNEDemandElement* walk = new GNEWalk(myNet, personParent, edges, arrivalPos);
783 if (myAllowUndoRedo) {
784 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " '" + personParent->getID() + "'");
786 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
788 } else {
790 // set child references
791 personParent->addChildElement(walk);
792 for (const auto& edge : edges) {
793 edge->addChildElement(walk);
794 }
795 walk->incRef("buildWalkEdges");
796 }
797 } else if (route) {
798 // create walk over route
799 GNEDemandElement* walk = new GNEWalk(myNet, personParent, route, arrivalPos);
800 if (myAllowUndoRedo) {
801 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " in '" + personParent->getID() + "'");
803 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
805 } else {
807 // set child references
808 personParent->addChildElement(walk);
809 route->addChildElement(walk);
810 walk->incRef("buildWalkRoute");
811 }
812 } else if (fromEdge && toEdge) {
813 // create walk from->to (edges)
814 GNEDemandElement* walk = new GNEWalk(myNet, personParent, fromEdge, toEdge, arrivalPos);
815 if (myAllowUndoRedo) {
816 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " in '" + personParent->getID() + "'");
818 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
820 } else {
822 // set child references
823 personParent->addChildElement(walk);
824 fromEdge->addChildElement(walk);
825 toEdge->addChildElement(walk);
826 walk->incRef("buildWalkFromTo");
827 }
828 } else if (fromEdge && toBusStop) {
829 // create walk from->busStop
830 GNEDemandElement* walk = new GNEWalk(false, myNet, personParent, fromEdge, toBusStop, arrivalPos);
831 if (myAllowUndoRedo) {
832 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " in '" + personParent->getID() + "'");
834 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
836 } else {
838 // set child references
839 personParent->addChildElement(walk);
840 fromEdge->addChildElement(walk);
841 toBusStop->addChildElement(walk);
842 walk->incRef("buildWalkFromBusStop");
843 }
844 } else if (fromEdge && toTrainStop) {
845 // create walk from->trainStop
846 GNEDemandElement* walk = new GNEWalk(true, myNet, personParent, fromEdge, toTrainStop, arrivalPos);
847 if (myAllowUndoRedo) {
848 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " in '" + personParent->getID() + "'");
850 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
852 } else {
854 // set child references
855 personParent->addChildElement(walk);
856 fromEdge->addChildElement(walk);
857 toTrainStop->addChildElement(walk);
858 walk->incRef("buildWalkFromTrainStop");
859 }
860 } else if (fromJunction && toJunction) {
861 // create walk from->to (junction)
862 GNEDemandElement* walk = new GNEWalk(myNet, personParent, fromJunction, toJunction, arrivalPos);
863 if (myAllowUndoRedo) {
864 myNet->getViewNet()->getUndoList()->begin(walk->getTagProperty().getGUIIcon(), TL("add ") + walk->getTagStr() + " in '" + personParent->getID() + "'");
866 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(walk, true), true);
868 } else {
870 // set child references
871 personParent->addChildElement(walk);
872 fromJunction->addChildElement(walk);
873 toJunction->addChildElement(walk);
874 walk->incRef("buildWalkFromTo");
875 }
876 }
877 }
878}
879
880
881void
882GNERouteHandler::buildRide(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& toEdgeID,
883 const std::string& toBusStopID, const std::string& toTrainStopID, double arrivalPos, const std::vector<std::string>& lines) {
884 // get previous plan edge
885 const auto previousEdge = getPreviousPlanEdge(true, sumoBaseObject);
886 // parse parents
887 GNEDemandElement* personParent = getPersonParent(sumoBaseObject);
888 GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
889 GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
891 GNEAdditional* toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toTrainStopID, false);
892 // chek if we're parsing the train stop as a busStop
893 if ((toBusStop == nullptr) && (toTrainStop == nullptr)) {
894 toBusStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, toTrainStopID, false);
895 toTrainStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, toBusStopID, false);
896 }
897 // check from edge
898 if ((fromEdge == nullptr) && previousEdge) {
899 fromEdge = previousEdge;
900 }
901 // check conditions
902 if (personParent && fromEdge) {
903 if (toEdge) {
904 // create ride from->to
905 GNEDemandElement* ride = new GNERide(myNet, personParent, fromEdge, toEdge, arrivalPos, lines);
906 if (myAllowUndoRedo) {
907 myNet->getViewNet()->getUndoList()->begin(ride->getTagProperty().getGUIIcon(), TL("add ") + ride->getTagStr() + " in '" + personParent->getID() + "'");
909 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
911 } else {
913 // set child references
914 personParent->addChildElement(ride);
915 fromEdge->addChildElement(ride);
916 toEdge->addChildElement(ride);
917 ride->incRef("buildRideFromTo");
918 }
919 } else if (toBusStop) {
920 // create ride from->busStop
921 GNEDemandElement* ride = new GNERide(false, myNet, personParent, fromEdge, toBusStop, arrivalPos, lines);
922 if (myAllowUndoRedo) {
923 myNet->getViewNet()->getUndoList()->begin(ride->getTagProperty().getGUIIcon(), TL("add ") + ride->getTagStr() + " in '" + personParent->getID() + "'");
925 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
927 } else {
929 // set child references
930 personParent->addChildElement(ride);
931 fromEdge->addChildElement(ride);
932 toBusStop->addChildElement(ride);
933 ride->incRef("buildRideFromBusStop");
934 }
935 } else if (toTrainStop) {
936 // create ride from->trainStop
937 GNEDemandElement* ride = new GNERide(true, myNet, personParent, fromEdge, toTrainStop, arrivalPos, lines);
938 if (myAllowUndoRedo) {
939 myNet->getViewNet()->getUndoList()->begin(ride->getTagProperty().getGUIIcon(), TL("add ") + ride->getTagStr() + " in '" + personParent->getID() + "'");
941 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(ride, true), true);
943 } else {
945 // set child references
946 personParent->addChildElement(ride);
947 fromEdge->addChildElement(ride);
948 toTrainStop->addChildElement(ride);
949 ride->incRef("buildRideFromTrainStop");
950 }
951 }
952 }
953}
954
955
956void
958 // first check if ID is duplicated
959 if (!isContainerIdDuplicated(containerParameters.id)) {
960 // obtain type
962 // try to parse type distribution
963 if (type == nullptr) {
965 }
966 if (type == nullptr) {
967 writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerParameters.vtypeid, toString(containerParameters.tag), containerParameters.id));
968 } else {
969 // create container using containerParameters
970 GNEDemandElement* container = new GNEContainer(SUMO_TAG_CONTAINER, myNet, type, containerParameters);
971 if (myAllowUndoRedo) {
972 myNet->getViewNet()->getUndoList()->begin(GUIIcon::CONTAINER, TL("add ") + container->getTagStr() + " '" + container->getID() + "'");
974 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(container, true), true);
976 } else {
978 // set container as child of type
979 type->addChildElement(container);
980 container->incRef("buildContainer");
981 }
982 }
983 }
984}
985
986
987void
988GNERouteHandler::buildContainerFlow(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const SUMOVehicleParameter& containerFlowParameters) {
989 // first check if ID is duplicated
990 if (!isContainerIdDuplicated(containerFlowParameters.id)) {
991 // obtain type
992 GNEDemandElement* type = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, containerFlowParameters.vtypeid, false);
993 // try to parse type distribution
994 if (type == nullptr) {
995 type = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE_DISTRIBUTION, containerFlowParameters.vtypeid, false);
996 }
997 if (type == nullptr) {
998 writeError(TLF("Invalid vehicle type '%' used in % '%'.", containerFlowParameters.vtypeid, toString(containerFlowParameters.tag), containerFlowParameters.id));
999 } else {
1000 // create containerFlow using containerFlowParameters
1001 GNEDemandElement* containerFlow = new GNEContainer(SUMO_TAG_CONTAINERFLOW, myNet, type, containerFlowParameters);
1002 if (myAllowUndoRedo) {
1003 myNet->getViewNet()->getUndoList()->begin(GUIIcon::CONTAINERFLOW, TL("add ") + containerFlow->getTagStr() + " '" + containerFlow->getID() + "'");
1005 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(containerFlow, true), true);
1007 } else {
1009 // set containerFlow as child of type
1010 type->addChildElement(containerFlow);
1011 containerFlow->incRef("buildContainerFlow");
1012 }
1013 }
1014 }
1015}
1016
1017
1018void
1019GNERouteHandler::buildTransport(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& toEdgeID,
1020 const std::string& toContainerStopID, const std::vector<std::string>& lines, const double arrivalPos) {
1021 // get previous plan edge
1022 const auto previousEdge = getPreviousPlanEdge(false, sumoBaseObject);
1023 // first parse parents
1024 GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1025 GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
1026 GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
1027 GNEAdditional* toContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, toContainerStopID, false);
1028 // check from edge
1029 if ((fromEdge == nullptr) && previousEdge) {
1030 fromEdge = previousEdge;
1031 }
1032 // check conditions
1033 if (containerParent && fromEdge) {
1034 if (toEdge) {
1035 // create transport from->to
1036 GNEDemandElement* transport = new GNETransport(myNet, containerParent, fromEdge, toEdge, lines, arrivalPos);
1037 if (myAllowUndoRedo) {
1038 myNet->getViewNet()->getUndoList()->begin(transport->getTagProperty().getGUIIcon(), TL("add ") + transport->getTagStr() + " in '" + containerParent->getID() + "'");
1040 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
1042 } else {
1044 // set child references
1045 containerParent->addChildElement(transport);
1046 fromEdge->addChildElement(transport);
1047 toEdge->addChildElement(transport);
1048 transport->incRef("buildTransportFromTo");
1049 }
1050 } else if (toContainerStop) {
1051 // create transport from->containerStop
1052 GNEDemandElement* transport = new GNETransport(myNet, containerParent, fromEdge, toContainerStop, lines, arrivalPos);
1053 if (myAllowUndoRedo) {
1054 myNet->getViewNet()->getUndoList()->begin(transport->getTagProperty().getGUIIcon(), TL("add ") + transport->getTagStr() + " in '" + containerParent->getID() + "'");
1056 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(transport, true), true);
1058 } else {
1060 // set child references
1061 containerParent->addChildElement(transport);
1062 fromEdge->addChildElement(transport);
1063 toContainerStop->addChildElement(transport);
1064 transport->incRef("buildTransportFromContainerStop");
1065 }
1066 }
1067 }
1068}
1069
1070
1071void
1072GNERouteHandler::buildTranship(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID, const std::string& toEdgeID,
1073 const std::string& toContainerStopID, const std::vector<std::string>& edgeIDs, const double speed, const double departPosition, const double arrivalPosition) {
1074 // get previous plan edge
1075 const auto previousEdge = getPreviousPlanEdge(false, sumoBaseObject);
1076 // first parse parents
1077 GNEDemandElement* containerParent = getContainerParent(sumoBaseObject);
1078 GNEEdge* fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);
1079 GNEEdge* toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);
1080 GNEAdditional* toContainerStop = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, toContainerStopID, false);
1081 std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_WALK, edgeIDs);
1082 // avoid consecutive duplicated edges
1083 edges.erase(std::unique(edges.begin(), edges.end()), edges.end());
1084 // check from edge
1085 if ((fromEdge == nullptr) && previousEdge) {
1086 fromEdge = previousEdge;
1087 }
1088 // check conditions
1089 if (containerParent && (fromEdge || (edges.size() > 0))) {
1090 if (edges.size() > 0) {
1091 // create tranship edges
1092 GNEDemandElement* tranship = new GNETranship(myNet, containerParent, edges, speed, departPosition, arrivalPosition);
1093 if (myAllowUndoRedo) {
1094 myNet->getViewNet()->getUndoList()->begin(tranship->getTagProperty().getGUIIcon(), TL("add ") + tranship->getTagStr() + " in '" + containerParent->getID() + "'");
1096 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
1098 } else {
1100 // set child references
1101 containerParent->addChildElement(tranship);
1102 for (const auto& edge : edges) {
1103 edge->addChildElement(tranship);
1104 }
1105 tranship->incRef("buildTranshipEdges");
1106 }
1107 } else if (toEdge) {
1108 // create tranship from->to
1109 GNEDemandElement* tranship = new GNETranship(myNet, containerParent, fromEdge, toEdge, speed, departPosition, arrivalPosition);
1110 if (myAllowUndoRedo) {
1111 myNet->getViewNet()->getUndoList()->begin(tranship->getTagProperty().getGUIIcon(), TL("add ") + tranship->getTagStr() + " in '" + containerParent->getID() + "'");
1113 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
1115 } else {
1117 // set child references
1118 containerParent->addChildElement(tranship);
1119 fromEdge->addChildElement(tranship);
1120 toEdge->addChildElement(tranship);
1121 tranship->incRef("buildTranshipFromTo");
1122 }
1123 } else if (toContainerStop) {
1124 // create tranship from->containerStop
1125 GNEDemandElement* tranship = new GNETranship(myNet, containerParent, fromEdge, toContainerStop, speed, departPosition, arrivalPosition);
1126 if (myAllowUndoRedo) {
1127 myNet->getViewNet()->getUndoList()->begin(tranship->getTagProperty().getGUIIcon(), TL("add ") + tranship->getTagStr() + " '" + containerParent->getID() + "'");
1129 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(tranship, true), true);
1131 } else {
1133 // set child references
1134 containerParent->addChildElement(tranship);
1135 fromEdge->addChildElement(tranship);
1136 toContainerStop->addChildElement(tranship);
1137 tranship->incRef("buildTranshipFromContainerStop");
1138 }
1139 }
1140 }
1141}
1142
1143
1144void
1146 // get obj parent
1147 const auto objParent = sumoBaseObject->getParentSumoBaseObject();
1148 // set tag
1149 SumoXMLTag tag = objParent->getTag();
1150 if (!objParent->hasStringAttribute(SUMO_ATTR_ROUTE) && !objParent->hasStringAttribute(SUMO_ATTR_FROM) && !objParent->hasStringAttribute(SUMO_ATTR_TO)) {
1151 if (tag == SUMO_TAG_VEHICLE) {
1153 } else if (tag == SUMO_TAG_FLOW) {
1155 }
1156 }
1157 // special case for flows over route
1158 if (objParent->hasStringAttribute(SUMO_ATTR_ROUTE) && (objParent->getTag() == SUMO_TAG_FLOW)) {
1159 tag = GNE_TAG_FLOW_ROUTE;
1160 }
1161 // get stop parent
1162 GNEDemandElement* stopParent = myNet->getAttributeCarriers()->retrieveDemandElement(tag, objParent->getStringAttribute(SUMO_ATTR_ID), false);
1163 // check if stopParent exist
1164 if (stopParent) {
1165 // flag for waypoint (is like a stop, but with extra attribute speed)
1166 bool waypoint = false;
1167 // avoid waypoints for person and containers
1168 if (!stopParent->getTagProperty().isPerson() && !stopParent->getTagProperty().isContainer()) {
1169 waypoint = (sumoBaseObject->getStopParameter().parametersSet & STOP_SPEED_SET) || (sumoBaseObject->getStopParameter().speed > 0);
1170 }
1171 // declare pointers to parent elements
1172 GNEAdditional* stoppingPlace = nullptr;
1173 GNELane* lane = nullptr;
1174 GNEEdge* edge = nullptr;
1175 // declare stopTagType
1176 SumoXMLTag stopTagType = SUMO_TAG_NOTHING;
1177 bool validParentDemandElement = true;
1178 // check conditions
1179 if (stopParameters.busstop.size() > 0) {
1180 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_BUS_STOP, stopParameters.busstop, false);
1181 stopTagType = waypoint ? GNE_TAG_WAYPOINT_BUSSTOP : GNE_TAG_STOP_BUSSTOP;
1182 // check if is a train stop
1183 if (stoppingPlace == nullptr) {
1184 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRAIN_STOP, stopParameters.busstop, false);
1185 stopTagType = waypoint ? GNE_TAG_WAYPOINT_TRAINSTOP : GNE_TAG_STOP_TRAINSTOP;
1186 }
1187 // containers cannot stops in busStops
1188 if (stopParent->getTagProperty().isContainer()) {
1189 writeError(TL("Containers don't support stops at busStops or trainStops"));
1190 validParentDemandElement = false;
1191 }
1192 } else if (stopParameters.containerstop.size() > 0) {
1193 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, stopParameters.containerstop, false);
1195 // persons cannot stops in containerStops
1196 if (stopParent->getTagProperty().isPerson()) {
1197 writeError(TL("Persons don't support stops at containerStops"));
1198 validParentDemandElement = false;
1199 }
1200 } else if (stopParameters.chargingStation.size() > 0) {
1203 // check person and containers
1204 if (stopParent->getTagProperty().isPerson()) {
1205 writeError(TL("Persons don't support stops at chargingStations"));
1206 validParentDemandElement = false;
1207 } else if (stopParent->getTagProperty().isContainer()) {
1208 writeError(TL("Containers don't support stops at chargingStations"));
1209 validParentDemandElement = false;
1210 }
1211 } else if (stopParameters.parkingarea.size() > 0) {
1212 stoppingPlace = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, stopParameters.parkingarea, false);
1213 stopTagType = waypoint ? GNE_TAG_WAYPOINT_PARKINGAREA : GNE_TAG_STOP_PARKINGAREA;
1214 // check person and containers
1215 if (stopParent->getTagProperty().isPerson()) {
1216 writeError(TL("Persons don't support stops at parkingAreas"));
1217 validParentDemandElement = false;
1218 } else if (stopParent->getTagProperty().isContainer()) {
1219 writeError(TL("Containers don't support stops at parkingAreas"));
1220 validParentDemandElement = false;
1221 }
1222 } else if (stopParameters.lane.size() > 0) {
1223 lane = myNet->getAttributeCarriers()->retrieveLane(stopParameters.lane, false);
1224 stopTagType = waypoint ? GNE_TAG_WAYPOINT_LANE : GNE_TAG_STOP_LANE;
1225 } else if (stopParameters.edge.size() > 0) {
1226 edge = myNet->getAttributeCarriers()->retrieveEdge(stopParameters.edge, false);
1227 // check vehicles
1228 if (stopParent->getTagProperty().isVehicle()) {
1229 writeError(TL("vehicles don't support stops at edges"));
1230 validParentDemandElement = false;
1231 }
1232 }
1233 // overwrite lane with edge parent if we're handling a personStop
1234 if (lane && (stopParent->getTagProperty().isPerson() || stopParent->getTagProperty().isContainer())) {
1235 edge = lane->getParentEdge();
1236 lane = nullptr;
1237 }
1238 // first check that parent is valid
1239 if (validParentDemandElement) {
1240 // check if values are correct
1241 if (stoppingPlace && lane && edge) {
1242 writeError(TL("A stop must be defined either over a stoppingPlace, a edge or a lane"));
1243 } else if (!stoppingPlace && !lane && !edge) {
1244 writeError(TL("A stop requires only a stoppingPlace, edge or lane"));
1245 } else if (stoppingPlace) {
1246 // create stop using stopParameters and stoppingPlace
1247 GNEDemandElement* stop = nullptr;
1248 if (stopParent->getTagProperty().isPerson()) {
1249 if (stoppingPlace->getTagProperty().getTag() == SUMO_TAG_BUS_STOP) {
1250 stop = new GNEStop(GNE_TAG_STOPPERSON_BUSSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1251 } else {
1252 stop = new GNEStop(GNE_TAG_STOPPERSON_TRAINSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1253 }
1254 } else if (stopParent->getTagProperty().isContainer()) {
1255 stop = new GNEStop(GNE_TAG_STOPCONTAINER_CONTAINERSTOP, myNet, stopParent, stoppingPlace, stopParameters);
1256 } else {
1257 stop = new GNEStop(stopTagType, myNet, stopParent, stoppingPlace, stopParameters);
1258 }
1259 // add it depending of undoDemandElements
1260 if (myAllowUndoRedo) {
1261 myNet->getViewNet()->getUndoList()->begin(stop->getTagProperty().getGUIIcon(), TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1263 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1265 } else {
1267 stoppingPlace->addChildElement(stop);
1268 stopParent->addChildElement(stop);
1269 stop->incRef("buildStoppingPlaceStop");
1270 }
1271 } else if (lane) {
1272 // create stop using stopParameters and lane (only for vehicles)
1273 GNEDemandElement* stop = new GNEStop(stopTagType, myNet, stopParent, lane, stopParameters);
1274 // add it depending of undoDemandElements
1275 if (myAllowUndoRedo) {
1276 myNet->getViewNet()->getUndoList()->begin(stop->getTagProperty().getGUIIcon(), TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1278 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1280 } else {
1282 lane->addChildElement(stop);
1283 stopParent->addChildElement(stop);
1284 stop->incRef("buildLaneStop");
1285 }
1286 } else {
1287 // create stop using stopParameters and edge
1288 GNEDemandElement* stop = nullptr;
1289 if (stopParent->getTagProperty().isPerson()) {
1290 stop = new GNEStop(GNE_TAG_STOPPERSON_EDGE, myNet, stopParent, edge, stopParameters);
1291 } else {
1292 stop = new GNEStop(GNE_TAG_STOPCONTAINER_EDGE, myNet, stopParent, edge, stopParameters);
1293 }
1294 // add it depending of undoDemandElements
1295 if (myAllowUndoRedo) {
1296 myNet->getViewNet()->getUndoList()->begin(stop->getTagProperty().getGUIIcon(), TL("add ") + stop->getTagStr() + " in '" + stopParent->getID() + "'");
1298 myNet->getViewNet()->getUndoList()->add(new GNEChange_DemandElement(stop, true), true);
1300 } else {
1302 edge->addChildElement(stop);
1303 stopParent->addChildElement(stop);
1304 stop->incRef("buildLaneStop");
1305 }
1306 }
1307 }
1308 }
1309}
1310
1311
1312bool
1314 GNEPathCreator* pathCreator, const bool centerAfterCreation) {
1315 // clear and set person object
1317 myPlanObject->setTag(personParent->getTagProperty().getTag());
1319 // declare personPlan object
1321 personPlanObject->setTag(tag);
1322 // get person plan attributes
1323 personPlanAttributes->getAttributesAndValues(personPlanObject, true);
1324 // get attributes
1325 const std::vector<std::string> types = personPlanObject->hasStringListAttribute(SUMO_ATTR_VTYPES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_VTYPES) : std::vector<std::string>();
1326 const std::vector<std::string> modes = personPlanObject->hasStringListAttribute(SUMO_ATTR_MODES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_MODES) : std::vector<std::string>();
1327 const std::vector<std::string> lines = personPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? personPlanObject->getStringListAttribute(SUMO_ATTR_LINES) : std::vector<std::string>();
1328 const double arrivalPos = personPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? personPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) : -1;
1329 // get stop parameters
1330 SUMOVehicleParameter::Stop stopParameters;
1331 // fill stops parameters
1333 stopParameters.actType = personPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE);
1334 if (personPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1335 stopParameters.duration = personPlanObject->getTimeAttribute(SUMO_ATTR_DURATION);
1336 stopParameters.parametersSet |= STOP_DURATION_SET;
1337 }
1338 if (personPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1339 stopParameters.until = personPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL);
1340 stopParameters.parametersSet |= STOP_UNTIL_SET;
1341 }
1342 }
1343 // get edges
1344 GNEEdge* fromEdge = (pathCreator->getSelectedEdges().size() > 0) ? pathCreator->getSelectedEdges().front() : nullptr;
1345 GNEEdge* toEdge = (pathCreator->getSelectedEdges().size() > 0) ? pathCreator->getSelectedEdges().back() : nullptr;
1346 // get junctions
1347 GNEJunction* fromJunction = (pathCreator->getSelectedJunctions().size() > 0) ? pathCreator->getSelectedJunctions().front() : nullptr;
1348 GNEJunction* toJunction = (pathCreator->getSelectedJunctions().size() > 0) ? pathCreator->getSelectedJunctions().back() : nullptr;
1349 // get busStop
1350 GNEAdditional* toBusStop = pathCreator->getToStoppingPlace(SUMO_TAG_BUS_STOP);
1351 GNEAdditional* toTrainStop = pathCreator->getToStoppingPlace(SUMO_TAG_TRAIN_STOP);
1352 // get path edges
1353 std::vector<std::string> edges;
1354 for (const auto& path : pathCreator->getPath()) {
1355 for (const auto& edge : path.getSubPath()) {
1356 edges.push_back(edge->getID());
1357 }
1358 }
1359 // get route
1360 GNEDemandElement* route = pathCreator->getRoute();
1361 // check what PersonPlan we're creating
1362 switch (tag) {
1363 // Person Trips
1365 // check if person trip busStop->edge can be created
1366 if (fromEdge && toEdge) {
1367 buildPersonTrip(personPlanObject, fromEdge->getID(), toEdge->getID(), "", "", "", "", arrivalPos, types, modes, lines);
1368 } else {
1369 myNet->getViewNet()->setStatusBarText(TL("A person trip from edge to edge needs two edges edge"));
1370 return false;
1371 }
1372 break;
1373 }
1375 // check if person trip busStop->busStop can be created
1376 if (fromEdge && toBusStop) {
1377 buildPersonTrip(personPlanObject, fromEdge->getID(), "", "", "", toBusStop->getID(), "", arrivalPos, types, modes, lines);
1378 } else {
1379 myNet->getViewNet()->setStatusBarText(TL("A person trip from edge to busStop needs one edge and one busStop"));
1380 return false;
1381 }
1382 break;
1383 }
1385 // check if person trip trainStop->trainStop can be created
1386 if (fromEdge && toTrainStop) {
1387 buildPersonTrip(personPlanObject, fromEdge->getID(), "", "", "", "", toTrainStop->getID(), arrivalPos, types, modes, lines);
1388 } else {
1389 myNet->getViewNet()->setStatusBarText(TL("A person trip from edge to trainStop needs one edge and one trainStop"));
1390 return false;
1391 }
1392 break;
1393 }
1395 // check if person trip busStop->junction can be created
1396 if (fromJunction && toJunction) {
1397 buildPersonTrip(personPlanObject, "", "", fromJunction->getID(), toJunction->getID(), "", "", arrivalPos, types, modes, lines);
1398 } else {
1399 myNet->getViewNet()->setStatusBarText(TL("A person trip from junction to junction needs two junctions junction"));
1400 return false;
1401 }
1402 break;
1403 }
1404 // Walks
1405 case GNE_TAG_WALK_EDGE: {
1406 // check if transport busStop->edge can be created
1407 if (fromEdge && toEdge) {
1408 buildWalk(personPlanObject, fromEdge->getID(), toEdge->getID(), "", "", "", "", {}, "", arrivalPos);
1409 } else {
1410 myNet->getViewNet()->setStatusBarText(TL("A walk to edge needs a busStop and an edge"));
1411 return false;
1412 }
1413 break;
1414 }
1415 case GNE_TAG_WALK_BUSSTOP: {
1416 // check if transport busStop->busStop can be created
1417 if (fromEdge && toBusStop) {
1418 buildWalk(personPlanObject, fromEdge->getID(), "", "", "", toBusStop->getID(), "", {}, "", arrivalPos);
1419 } else {
1420 myNet->getViewNet()->setStatusBarText(TL("A walk to busStop needs two busStops"));
1421 return false;
1422 }
1423 break;
1424 }
1426 // check if transport trainStop->trainStop can be created
1427 if (fromEdge && toTrainStop) {
1428 buildWalk(personPlanObject, fromEdge->getID(), "", "", "", "", toTrainStop->getID(), {}, "", arrivalPos);
1429 } else {
1430 myNet->getViewNet()->setStatusBarText(TL("A walk to trainStop needs two trainStops"));
1431 return false;
1432 }
1433 break;
1434 }
1435 case GNE_TAG_WALK_EDGES: {
1436 // check if transport edges can be created
1437 if (edges.size() > 0) {
1438 buildWalk(personPlanObject, "", "", "", "", "", "", edges, "", arrivalPos);
1439 } else {
1440 myNet->getViewNet()->setStatusBarText(TL("A walk with edges needs a list of edges"));
1441 return false;
1442 }
1443 break;
1444 }
1445 case GNE_TAG_WALK_ROUTE: {
1446 // check if transport edges can be created
1447 if (route) {
1448 buildWalk(personPlanObject, "", "", "", "", "", "", {}, route->getID(), arrivalPos);
1449 } else {
1450 myNet->getViewNet()->setStatusBarText(TL("A route walk needs a route"));
1451 return false;
1452 }
1453 break;
1454 }
1456 // check if transport busStop->junction can be created
1457 if (fromJunction && toJunction) {
1458 buildWalk(personPlanObject, "", "", fromJunction->getID(), toJunction->getID(), "", "", {}, "", arrivalPos);
1459 } else {
1460 myNet->getViewNet()->setStatusBarText(TL("A ride from busStop to junction needs a busStop and an junction"));
1461 return false;
1462 }
1463 break;
1464 }
1465 // Rides
1466 case GNE_TAG_RIDE_EDGE: {
1467 // check if ride edge->edge can be created
1468 if (fromEdge && toEdge) {
1469 buildRide(personPlanObject, fromEdge->getID(), toEdge->getID(), "", "", arrivalPos, lines);
1470 } else {
1471 myNet->getViewNet()->setStatusBarText(TL("A ride from edge to edge needs two edges edge"));
1472 return false;
1473 }
1474 break;
1475 }
1476 case GNE_TAG_RIDE_BUSSTOP: {
1477 // check if ride edge->busStop can be created
1478 if (fromEdge && toBusStop) {
1479 buildRide(personPlanObject, fromEdge->getID(), "", toBusStop->getID(), "", arrivalPos, lines);
1480 } else {
1481 myNet->getViewNet()->setStatusBarText(TL("A ride from edge to busStop needs one edge and one busStop"));
1482 return false;
1483 }
1484 break;
1485 }
1487 // check if ride edge->trainStop can be created
1488 if (fromEdge && toTrainStop) {
1489 buildRide(personPlanObject, fromEdge->getID(), "", "", toTrainStop->getID(), arrivalPos, lines);
1490 } else {
1491 myNet->getViewNet()->setStatusBarText(TL("A ride from edge to trainStop needs one edge and one trainStop"));
1492 return false;
1493 }
1494 break;
1495 }
1496 // stops
1498 // check if ride busStop->busStop can be created
1499 if (fromEdge) {
1500 stopParameters.edge = fromEdge->getID();
1501 stopParameters.endPos = fromEdge->getLanes().front()->getLaneShape().nearest_offset_to_point2D(myNet->getViewNet()->getPositionInformation());
1502 stopParameters.parametersSet |= STOP_END_SET;
1503 buildStop(personPlanObject, stopParameters);
1504 } else {
1505 myNet->getViewNet()->setStatusBarText(TL("A stop has to be placed over an edge"));
1506 return false;
1507 }
1508 break;
1509 }
1511 // check if ride busStop->busStop can be created
1512 if (toBusStop) {
1513 stopParameters.busstop = toBusStop->getID();
1514 buildStop(personPlanObject, stopParameters);
1515 } else {
1516 myNet->getViewNet()->setStatusBarText(TL("A stop has to be placed over a busStop"));
1517 return false;
1518 }
1519 break;
1520 }
1522 // check if ride trainStop->trainStop can be created
1523 if (toTrainStop) {
1524 stopParameters.busstop = toTrainStop->getID();
1525 buildStop(personPlanObject, stopParameters);
1526 } else {
1527 myNet->getViewNet()->setStatusBarText(TL("A stop has to be placed over a trainStop"));
1528 return false;
1529 }
1530 break;
1531 }
1532 default:
1533 throw InvalidArgument("Invalid person plan tag");
1534 }
1535 // get person
1536 const auto person = myNet->getAttributeCarriers()->retrieveDemandElement(personPlanObject->getParentSumoBaseObject()->getTag(),
1537 personPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1538 if (person) {
1539 // compute person (and all person plans)
1540 person->computePathElement();
1541 // center view after creation
1542 if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(person->getPositionInView())) {
1543 myNet->getViewNet()->centerTo(person->getPositionInView(), false);
1544 }
1545 }
1546 return true;
1547}
1548
1549
1550bool
1551GNERouteHandler::buildContainerPlan(SumoXMLTag tag, GNEDemandElement* containerParent, GNEAttributesCreator* containerPlanAttributes, GNEPathCreator* pathCreator, const bool centerAfterCreation) {
1552 // clear and set planObject
1554 myPlanObject->setTag(containerParent->getTagProperty().getTag());
1555 myPlanObject->addStringAttribute(SUMO_ATTR_ID, containerParent->getID());
1556 // declare containerPlan object
1558 containerPlanObject->setTag(tag);
1559 // get attributes and values
1560 containerPlanAttributes->getAttributesAndValues(containerPlanObject, true);
1561 // get attributes
1562 const std::vector<std::string> lines = containerPlanObject->hasStringListAttribute(SUMO_ATTR_LINES) ? containerPlanObject->getStringListAttribute(SUMO_ATTR_LINES) : std::vector<std::string>();
1563 const double speed = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_SPEED) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_SPEED) : 1.39;
1564 const double departPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_DEPARTPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_DEPARTPOS) : -1;
1565 const double arrivalPos = containerPlanObject->hasDoubleAttribute(SUMO_ATTR_ARRIVALPOS) ? containerPlanObject->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS) : -1;
1566 // get stop parameters
1567 SUMOVehicleParameter::Stop stopParameters;
1568 // fill stops parameters
1570 stopParameters.actType = containerPlanObject->getStringAttribute(SUMO_ATTR_ACTTYPE);
1571 if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_DURATION)) {
1572 stopParameters.duration = containerPlanObject->getTimeAttribute(SUMO_ATTR_DURATION);
1573 stopParameters.parametersSet |= STOP_DURATION_SET;
1574 }
1575 if (containerPlanObject->hasTimeAttribute(SUMO_ATTR_UNTIL)) {
1576 stopParameters.until = containerPlanObject->getTimeAttribute(SUMO_ATTR_UNTIL);
1577 stopParameters.parametersSet |= STOP_UNTIL_SET;
1578 }
1579 }
1580 // get edges
1581 GNEEdge* fromEdge = (pathCreator->getSelectedEdges().size() > 0) ? pathCreator->getSelectedEdges().front() : nullptr;
1582 GNEEdge* toEdge = (pathCreator->getSelectedEdges().size() > 0) ? pathCreator->getSelectedEdges().back() : nullptr;
1583 // get containerStop
1584 GNEAdditional* toContainerStop = pathCreator->getToStoppingPlace(SUMO_TAG_CONTAINER_STOP);
1585 // get path edges
1586 std::vector<std::string> edges;
1587 for (const auto& path : pathCreator->getPath()) {
1588 for (const auto& edge : path.getSubPath()) {
1589 edges.push_back(edge->getID());
1590 }
1591 }
1592 // check what ContainerPlan we're creating
1593 switch (tag) {
1594 // Transports
1596 // check if transport busStop->edge can be created
1597 if (fromEdge && toEdge) {
1598 buildTransport(containerPlanObject, fromEdge->getID(), toEdge->getID(), "", lines, arrivalPos);
1599 } else {
1600 myNet->getViewNet()->setStatusBarText(TL("A ride from busStop to edge needs a busStop and an edge"));
1601 return false;
1602 }
1603 break;
1604 }
1606 // check if transport busStop->busStop can be created
1607 if (fromEdge && toContainerStop) {
1608 buildTransport(containerPlanObject, fromEdge->getID(), "", toContainerStop->getID(), lines, arrivalPos);
1609 } else {
1610 myNet->getViewNet()->setStatusBarText(TL("A transport from busStop to busStop needs two busStops"));
1611 return false;
1612 }
1613 break;
1614 }
1615 // Tranships
1616 case GNE_TAG_TRANSHIP_EDGE: {
1617 // check if tranship busStop->edge can be created
1618 if (fromEdge && toEdge) {
1619 buildTranship(containerPlanObject, fromEdge->getID(), toEdge->getID(), "", {}, speed, departPos, arrivalPos);
1620 } else {
1621 myNet->getViewNet()->setStatusBarText(TL("A ride from busStop to edge needs a busStop and an edge"));
1622 return false;
1623 }
1624 break;
1625 }
1627 // check if tranship busStop->busStop can be created
1628 if (fromEdge && toContainerStop) {
1629 buildTranship(containerPlanObject, fromEdge->getID(), "", toContainerStop->getID(), {}, speed, departPos, arrivalPos);
1630 } else {
1631 myNet->getViewNet()->setStatusBarText(TL("A tranship from busStop to busStop needs two busStops"));
1632 return false;
1633 }
1634 break;
1635 }
1637 // check if tranship edges can be created
1638 if (edges.size() > 0) {
1639 buildTranship(containerPlanObject, "", "", "", edges, speed, departPos, arrivalPos);
1640 } else {
1641 myNet->getViewNet()->setStatusBarText(TL("A tranship with edges attribute needs a list of edges"));
1642 return false;
1643 }
1644 break;
1645 }
1646 // stops
1648 // check if ride busStop->busStop can be created
1649 if (fromEdge) {
1650 stopParameters.edge = fromEdge->getID();
1651 stopParameters.endPos = fromEdge->getLanes().front()->getLaneShape().nearest_offset_to_point2D(myNet->getViewNet()->getPositionInformation());
1652 stopParameters.parametersSet |= STOP_END_SET;
1653 buildStop(containerPlanObject, stopParameters);
1654 } else {
1655 myNet->getViewNet()->setStatusBarText(TL("A stop has to be placed over an edge"));
1656 return false;
1657 }
1658 break;
1659 }
1661 // check if ride busStop->busStop can be created
1662 if (toContainerStop) {
1663 stopParameters.containerstop = toContainerStop->getID();
1664 buildStop(containerPlanObject, stopParameters);
1665 } else {
1666 myNet->getViewNet()->setStatusBarText(TL("A stop has to be placed over a busStop"));
1667 return false;
1668 }
1669 break;
1670 }
1671 default:
1672 throw InvalidArgument("Invalid container plan tag");
1673 }
1674 // get container
1675 const auto container = myNet->getAttributeCarriers()->retrieveDemandElement(containerPlanObject->getParentSumoBaseObject()->getTag(),
1676 containerPlanObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);
1677 if (container) {
1678 // compute container (and all container plans)
1679 container->computePathElement();
1680 // center view after creation
1681 if (centerAfterCreation && !myNet->getViewNet()->getVisibleBoundary().around(container->getPositionInView())) {
1682 myNet->getViewNet()->centerTo(container->getPositionInView(), false);
1683 }
1684 }
1685 return true;
1686}
1687
1688
1689bool
1691 // declare vehicle tags vector
1692 const std::vector<SumoXMLTag> vehicleTags = {SUMO_TAG_VEHICLE, GNE_TAG_VEHICLE_WITHROUTE, SUMO_TAG_TRIP, GNE_TAG_TRIP_TAZS,
1694 for (const auto& vehicleTag : vehicleTags) {
1695 if (!checkDuplicatedDemandElement(vehicleTag, id)) {
1696 writeError(TLF("There is another % with the same ID='%'.", toString(vehicleTag), id));
1697 return true;
1698 }
1699 }
1700 return false;
1701}
1702
1703
1704bool
1705GNERouteHandler::isViaAttributeValid(const std::vector<std::string>& via) {
1706 for (const auto& edgeID : via) {
1707 if (myNet->getAttributeCarriers()->retrieveEdge(edgeID, false) == nullptr) {
1708 writeError(TLF("Via edge '%' doesn't exist.", edgeID));
1709 return false;
1710 }
1711 }
1712 return true;
1713}
1714
1715
1716bool
1718 for (SumoXMLTag personTag : std::vector<SumoXMLTag>({SUMO_TAG_PERSON, SUMO_TAG_PERSONFLOW})) {
1719 if (!checkDuplicatedDemandElement(personTag, id)) {
1720 writeError(TLF("There is another % with the same ID='%'.", toString(personTag), id));
1721 return true;
1722 }
1723 }
1724 return false;
1725}
1726
1727
1728bool
1730 for (SumoXMLTag containerTag : std::vector<SumoXMLTag>({SUMO_TAG_CONTAINER, SUMO_TAG_CONTAINERFLOW})) {
1731 if (!checkDuplicatedDemandElement(containerTag, id)) {
1732 writeError(TLF("There is another % with the same ID='%'.", toString(containerTag), id));
1733 return true;
1734 }
1735 }
1736 return false;
1737}
1738
1739
1740void
1741GNERouteHandler::transformToVehicle(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1742 // get original vehicle tag
1743 SumoXMLTag tag = originalVehicle->getTagProperty().getTag();
1744 // get pointer to net
1745 GNENet* net = originalVehicle->getNet();
1746 // check if transform after creation
1747 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1748 // declare route handler
1749 GNERouteHandler routeHandler("", net, true, false);
1750 // make a copy of the vehicle parameters
1751 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1752 // obtain vClass
1753 const auto vClass = originalVehicle->getVClass();
1754 // set "yellow" as original route color
1755 RGBColor routeColor = RGBColor::YELLOW;
1756 // declare edges
1757 std::vector<GNEEdge*> routeEdges;
1758 // obtain edges depending of tag
1759 if ((tag == GNE_TAG_FLOW_ROUTE) || (tag == SUMO_TAG_VEHICLE)) {
1760 // get route edges
1761 routeEdges = originalVehicle->getParentDemandElements().back()->getParentEdges();
1762 // get original route color
1763 routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1764 } else if (originalVehicle->getTagProperty().hasEmbeddedRoute()) {
1765 // get embedded route edges
1766 routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1767 } else if ((tag == SUMO_TAG_TRIP) || (tag == SUMO_TAG_FLOW)) {
1768 // calculate path using from-via-to edges
1769 routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1770 }
1771 // declare edge IDs
1772 std::vector<std::string> edgeIDs;
1773 for (const auto& edge : routeEdges) {
1774 edgeIDs.push_back(edge->getID());
1775 }
1776 // only continue if edges are valid
1777 if (routeEdges.empty()) {
1778 // declare header
1779 const std::string header = "Problem transforming to vehicle";
1780 // declare message
1781 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1782 // write warning
1783 WRITE_DEBUG("Opened FXMessageBox " + header);
1784 // open message box
1785 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1786 // write warning if netedit is running in testing mode
1787 WRITE_DEBUG("Closed FXMessageBox " + header);
1788 } else {
1789 // begin undo-redo operation
1790 net->getViewNet()->getUndoList()->begin(originalVehicle->getTagProperty().getGUIIcon(), "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1791 // first delete vehicle
1792 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1793 // check if new vehicle must have an embedded route
1794 if (createEmbeddedRoute) {
1795 // change tag in vehicle parameters
1796 vehicleParameters.tag = GNE_TAG_VEHICLE_WITHROUTE;
1797 // create a flow with embebbed routes
1799 CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1800 // fill parameters
1801 vehicleBaseOBject->setTag(SUMO_TAG_VEHICLE);
1802 vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1803 vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1804 // build embedded route
1805 routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1806 // delete vehicle base object
1807 delete vehicleBaseOBject;
1808 } else {
1809 // change tag in vehicle parameters
1810 vehicleParameters.tag = SUMO_TAG_VEHICLE;
1811 // generate route ID
1812 const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1813 // build route
1814 routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, {});
1815 // set route ID in vehicle parameters
1816 vehicleParameters.routeid = routeID;
1817 // create vehicle
1818 routeHandler.buildVehicleOverRoute(nullptr, vehicleParameters);
1819 }
1820 // end undo-redo operation
1821 net->getViewNet()->getUndoList()->end();
1822 // check if inspect
1823 if (inspectAfterTransform) {
1824 // get created element
1825 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1826 // inspect it
1827 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1828 }
1829 }
1830}
1831
1832
1833void
1834GNERouteHandler::transformToRouteFlow(GNEVehicle* originalVehicle, bool createEmbeddedRoute) {
1835 // get original vehicle tag
1836 SumoXMLTag tag = originalVehicle->getTagProperty().getTag();
1837 // get pointer to net
1838 GNENet* net = originalVehicle->getNet();
1839 // check if transform after creation
1840 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1841 // declare route handler
1842 GNERouteHandler routeHandler("", net, true, false);
1843 // obtain vehicle parameters
1844 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1845 // obtain vClass
1846 const auto vClass = originalVehicle->getVClass();
1847 // set "yellow" as original route color
1848 RGBColor routeColor = RGBColor::YELLOW;
1849 // declare edges
1850 std::vector<GNEEdge*> routeEdges;
1851 // obtain edges depending of tag
1852 if ((tag == GNE_TAG_FLOW_ROUTE) || (tag == SUMO_TAG_VEHICLE)) {
1853 // get route edges
1854 routeEdges = originalVehicle->getParentDemandElements().back()->getParentEdges();
1855 // get original route color
1856 routeColor = originalVehicle->getParentDemandElements().back()->getColor();
1857 } else if (originalVehicle->getTagProperty().hasEmbeddedRoute()) {
1858 // get embedded route edges
1859 routeEdges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1860 } else if ((tag == SUMO_TAG_TRIP) || (tag == SUMO_TAG_FLOW)) {
1861 // calculate path using from-via-to edges
1862 routeEdges = originalVehicle->getNet()->getPathManager()->getPathCalculator()->calculateDijkstraPath(originalVehicle->getVClass(), originalVehicle->getParentEdges());
1863 }
1864 // declare edge IDs
1865 std::vector<std::string> edgeIDs;
1866 for (const auto& edge : routeEdges) {
1867 edgeIDs.push_back(edge->getID());
1868 }
1869 // only continue if edges are valid
1870 if (routeEdges.empty()) {
1871 // declare header
1872 const std::string header = "Problem transforming to vehicle";
1873 // declare message
1874 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1875 // write warning
1876 WRITE_DEBUG("Opened FXMessageBox " + header);
1877 // open message box
1878 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1879 // write warning if netedit is running in testing mode
1880 WRITE_DEBUG("Closed FXMessageBox " + header);
1881 } else {
1882 // begin undo-redo operation
1883 net->getViewNet()->getUndoList()->begin(originalVehicle->getTagProperty().getGUIIcon(), "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
1884 // first delete vehicle
1885 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1886 // change depart
1887 if ((vehicleParameters.tag == SUMO_TAG_TRIP) || (vehicleParameters.tag == SUMO_TAG_VEHICLE) || (vehicleParameters.tag == GNE_TAG_VEHICLE_WITHROUTE)) {
1888 // get template flow
1890 // set flow parameters
1891 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
1892 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
1893 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
1894 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
1895 // by default, number and end enabled
1896 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
1897 }
1898 // check if new vehicle must have an embedded route
1899 if (createEmbeddedRoute) {
1900 // change tag in vehicle parameters
1901 vehicleParameters.tag = GNE_TAG_FLOW_WITHROUTE;
1902 // create a flow with embebbed routes
1904 CommonXMLStructure::SumoBaseObject* routeBaseOBject = new CommonXMLStructure::SumoBaseObject(vehicleBaseOBject);
1905 // fill parameters
1906 vehicleBaseOBject->setTag(SUMO_TAG_FLOW);
1907 vehicleBaseOBject->addStringAttribute(SUMO_ATTR_ID, vehicleParameters.id);
1908 vehicleBaseOBject->setVehicleParameter(&vehicleParameters);
1909 // build embedded route
1910 routeHandler.buildEmbeddedRoute(routeBaseOBject, edgeIDs, RGBColor::INVISIBLE, false, 0, {});
1911 // delete vehicle base object
1912 delete vehicleBaseOBject;
1913 } else {
1914 // change tag in vehicle parameters
1915 vehicleParameters.tag = GNE_TAG_FLOW_ROUTE;
1916 // generate a new route id
1917 const std::string routeID = net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE);
1918 // build route
1919 routeHandler.buildRoute(nullptr, routeID, vClass, edgeIDs, routeColor, false, 0, {});
1920 // set route ID in vehicle parameters
1921 vehicleParameters.routeid = routeID;
1922 // create vehicle
1923 routeHandler.buildFlowOverRoute(nullptr, vehicleParameters);
1924 }
1925 // end undo-redo operation
1926 net->getViewNet()->getUndoList()->end();
1927 // check if inspect
1928 if (inspectAfterTransform) {
1929 // get created element
1930 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1931 // inspect it
1932 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
1933 }
1934 }
1935}
1936
1937
1938void
1940 // get original vehicle tag
1941 SumoXMLTag tag = originalVehicle->getTagProperty().getTag();
1942 // get pointer to net
1943 GNENet* net = originalVehicle->getNet();
1944 // check if transform after creation
1945 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
1946 // declare route handler
1947 GNERouteHandler routeHandler("", net, true, false);
1948 // obtain vehicle parameters
1949 SUMOVehicleParameter vehicleParameters = *originalVehicle;
1950 // get route
1951 GNEDemandElement* route = nullptr;
1952 // declare edges
1953 std::vector<GNEEdge*> edges;
1954 // obtain edges depending of tag
1955 if ((tag == SUMO_TAG_VEHICLE) || (tag == GNE_TAG_FLOW_ROUTE)) {
1956 // set route
1957 route = originalVehicle->getParentDemandElements().back();
1958 // get route edges
1959 edges = route->getParentEdges();
1960 } else if (originalVehicle->getTagProperty().hasEmbeddedRoute()) {
1961 // get embedded route edges
1962 edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
1963 } else if ((tag == SUMO_TAG_TRIP) || (tag == SUMO_TAG_FLOW)) {
1964 // just take parent edges (from and to)
1965 edges = originalVehicle->getParentEdges();
1966 }
1967 // only continue if edges are valid
1968 if (edges.size() < 2) {
1969 // declare header
1970 const std::string header = "Problem transforming to vehicle";
1971 // declare message
1972 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
1973 // write warning
1974 WRITE_DEBUG("Opened FXMessageBox " + header);
1975 // open message box
1976 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
1977 // write warning if netedit is running in testing mode
1978 WRITE_DEBUG("Closed FXMessageBox " + header);
1979 } else {
1980 // begin undo-redo operation
1981 net->getViewNet()->getUndoList()->begin(originalVehicle->getTagProperty().getGUIIcon(), "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_TRIP));
1982 // first delete vehicle
1983 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
1984 // check if route has to be deleted
1985 if (route && route->getChildDemandElements().empty()) {
1986 net->deleteDemandElement(route, net->getViewNet()->getUndoList());
1987 }
1988 // change tag in vehicle parameters
1989 vehicleParameters.tag = SUMO_TAG_TRIP;
1990 // create trip
1991 routeHandler.buildTrip(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
1992 // end undo-redo operation
1993 net->getViewNet()->getUndoList()->end();
1994 // check if inspect
1995 if (inspectAfterTransform) {
1996 // get created element
1997 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
1998 // inspect it
1999 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2000 }
2001 }
2002}
2003
2004
2005void
2007 // get original vehicle tag
2008 SumoXMLTag tag = originalVehicle->getTagProperty().getTag();
2009 // get pointer to net
2010 GNENet* net = originalVehicle->getNet();
2011 // check if transform after creation
2012 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalVehicle);
2013 // declare route handler
2014 GNERouteHandler routeHandler("", net, true, false);
2015 // obtain vehicle parameters
2016 SUMOVehicleParameter vehicleParameters = *originalVehicle;
2017 // declare route
2018 GNEDemandElement* route = nullptr;
2019 // declare edges
2020 std::vector<GNEEdge*> edges;
2021 // obtain edges depending of tag
2022 if ((tag == SUMO_TAG_VEHICLE) || (tag == GNE_TAG_FLOW_ROUTE)) {
2023 // set route
2024 route = originalVehicle->getParentDemandElements().back();
2025 // get route edges
2026 edges = route->getParentEdges();
2027 } else if (originalVehicle->getTagProperty().hasEmbeddedRoute()) {
2028 // get embedded route edges
2029 edges = originalVehicle->getChildDemandElements().front()->getParentEdges();
2030 } else if ((tag == SUMO_TAG_TRIP) || (tag == SUMO_TAG_FLOW)) {
2031 // just take parent edges (from and to)
2032 edges = originalVehicle->getParentEdges();
2033 }
2034 // only continue if edges are valid
2035 if (edges.empty()) {
2036 // declare header
2037 const std::string header = "Problem transforming to vehicle";
2038 // declare message
2039 const std::string message = "Vehicle cannot be transformed. Invalid number of edges";
2040 // write warning
2041 WRITE_DEBUG("Opened FXMessageBox " + header);
2042 // open message box
2043 FXMessageBox::warning(originalVehicle->getNet()->getViewNet()->getApp(), MBOX_OK, header.c_str(), "%s", message.c_str());
2044 // write warning if netedit is running in testing mode
2045 WRITE_DEBUG("Closed FXMessageBox " + header);
2046 } else {
2047 // begin undo-redo operation
2048 net->getViewNet()->getUndoList()->begin(originalVehicle->getTagProperty().getGUIIcon(), "transform " + originalVehicle->getTagStr() + " to " + toString(SUMO_TAG_VEHICLE));
2049 // first delete vehicle
2050 net->deleteDemandElement(originalVehicle, net->getViewNet()->getUndoList());
2051 // check if route has to be deleted
2052 if (route && route->getChildDemandElements().empty()) {
2053 net->deleteDemandElement(route, net->getViewNet()->getUndoList());
2054 }
2055 // change depart
2056 if ((vehicleParameters.tag == SUMO_TAG_TRIP) || (vehicleParameters.tag == SUMO_TAG_VEHICLE) || (vehicleParameters.tag == GNE_TAG_VEHICLE_WITHROUTE)) {
2057 // get template flow
2059 // set flow parameters
2060 vehicleParameters.repetitionEnd = vehicleParameters.depart + string2time("3600");
2061 vehicleParameters.repetitionNumber = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(SUMO_ATTR_NUMBER));
2062 vehicleParameters.repetitionOffset = string2time(templateFlow->getAttribute(SUMO_ATTR_PERIOD));
2063 vehicleParameters.repetitionProbability = GNEAttributeCarrier::parse<double>(templateFlow->getAttribute(SUMO_ATTR_PROB));
2064 // by default, number and end enabled
2065 vehicleParameters.parametersSet = GNEAttributeCarrier::parse<int>(templateFlow->getAttribute(GNE_ATTR_FLOWPARAMETERS));
2066 }
2067 // change tag in vehicle parameters
2068 vehicleParameters.tag = SUMO_TAG_FLOW;
2069 // create flow
2070 routeHandler.buildFlow(nullptr, vehicleParameters, edges.front()->getID(), edges.back()->getID());
2071 // end undo-redo operation
2072 net->getViewNet()->getUndoList()->end();
2073 // check if inspect
2074 if (inspectAfterTransform) {
2075 // get created element
2076 auto transformedVehicle = net->getAttributeCarriers()->retrieveDemandElement(vehicleParameters.tag, vehicleParameters.id);
2077 // inspect it
2078 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedVehicle);
2079 }
2080 }
2081}
2082
2083
2084void
2086 // get pointer to net
2087 GNENet* net = originalPerson->getNet();
2088 // check if transform after creation
2089 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
2090 // declare route handler
2091 GNERouteHandler routeHandler("", net, true, false);
2092 // obtain person parameters
2093 SUMOVehicleParameter personParameters = *originalPerson;
2094 // get person plans
2095 const auto personPlans = originalPerson->getChildDemandElements();
2096 // save ID
2097 const auto ID = personParameters.id;
2098 // set dummy ID
2099 personParameters.id = "%dummyID%";
2100 // begin undo-redo operation
2101 net->getViewNet()->getUndoList()->begin(originalPerson->getTagProperty().getGUIIcon(), "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSON));
2102 // create personFlow
2103 routeHandler.buildPerson(nullptr, personParameters);
2104 // move all person plans to new person
2105 for (const auto& personPlan : personPlans) {
2106 personPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2107 }
2108 // delete original person plan
2109 net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2110 // restore ID of new person plan
2111 auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSON, "%dummyID%");
2112 newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2113 // finish undoList
2114 net->getViewNet()->getUndoList()->end();
2115 // check if inspect
2116 if (inspectAfterTransform) {
2117 // get created element
2118 auto transformedPerson = net->getAttributeCarriers()->retrieveDemandElement(personParameters.tag, personParameters.id);
2119 // inspect it
2120 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedPerson);
2121 }
2122}
2123
2124
2125void
2127 // get pointer to net
2128 GNENet* net = originalPerson->getNet();
2129 // check if transform after creation
2130 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalPerson);
2131 // declare route handler
2132 GNERouteHandler routeHandler("", net, true, false);
2133 // obtain person parameters
2134 SUMOVehicleParameter personParameters = *originalPerson;
2135 // get person plans
2136 const auto personPlans = originalPerson->getChildDemandElements();
2137 // save ID
2138 const auto ID = personParameters.id;
2139 // set dummy ID
2140 personParameters.id = "%dummyID%";
2141 // begin undo-redo operation
2142 net->getViewNet()->getUndoList()->begin(originalPerson->getTagProperty().getGUIIcon(), "transform " + originalPerson->getTagStr() + " to " + toString(SUMO_TAG_PERSONFLOW));
2143 // create personFlow
2144 routeHandler.buildPersonFlow(nullptr, personParameters);
2145 // move all person plans to new person
2146 for (const auto& personPlan : personPlans) {
2147 personPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2148 }
2149 // delete original person plan
2150 net->deleteDemandElement(originalPerson, net->getViewNet()->getUndoList());
2151 // restore ID of new person plan
2152 auto newPerson = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_PERSONFLOW, "%dummyID%");
2153 newPerson->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2154 // enable attributes
2155 newPerson->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2156 newPerson->enableAttribute(SUMO_ATTR_PERSONSPERHOUR, net->getViewNet()->getUndoList());
2157 // finish undoList
2158 net->getViewNet()->getUndoList()->end();
2159 // check if inspect
2160 if (inspectAfterTransform) {
2161 // get created element
2162 auto transformedPerson = net->getAttributeCarriers()->retrieveDemandElement(personParameters.tag, personParameters.id);
2163 // inspect it
2164 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedPerson);
2165 }
2166}
2167
2168
2169void
2171 // get pointer to net
2172 GNENet* net = originalContainer->getNet();
2173 // check if transform after creation
2174 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2175 // declare route handler
2176 GNERouteHandler routeHandler("", net, true, false);
2177 // obtain container parameters
2178 SUMOVehicleParameter containerParameters = *originalContainer;
2179 // get container plans
2180 const auto containerPlans = originalContainer->getChildDemandElements();
2181 // save ID
2182 const auto ID = containerParameters.id;
2183 // set dummy ID
2184 containerParameters.id = "%dummyID%";
2185 // begin undo-redo operation
2186 net->getViewNet()->getUndoList()->begin(originalContainer->getTagProperty().getGUIIcon(), "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINER));
2187 // create containerFlow
2188 routeHandler.buildContainer(nullptr, containerParameters);
2189 // move all container plans to new container
2190 for (const auto& containerPlan : containerPlans) {
2191 containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2192 }
2193 // delete original container plan
2194 net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2195 // restore ID of new container plan
2196 auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINER, "%dummyID%");
2197 newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2198 // finish undoList
2199 net->getViewNet()->getUndoList()->end();
2200 // check if inspect
2201 if (inspectAfterTransform) {
2202 // get created element
2203 auto transformedContainer = net->getAttributeCarriers()->retrieveDemandElement(containerParameters.tag, containerParameters.id);
2204 // inspect it
2205 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedContainer);
2206 }
2207}
2208
2209
2210void
2212 // get pointer to net
2213 GNENet* net = originalContainer->getNet();
2214 // check if transform after creation
2215 const bool inspectAfterTransform = net->getViewNet()->isAttributeCarrierInspected(originalContainer);
2216 // declare route handler
2217 GNERouteHandler routeHandler("", net, true, false);
2218 // obtain container parameters
2219 SUMOVehicleParameter containerParameters = *originalContainer;
2220 // get container plans
2221 const auto containerPlans = originalContainer->getChildDemandElements();
2222 // save ID
2223 const auto ID = containerParameters.id;
2224 // set dummy ID
2225 containerParameters.id = "%dummyID%";
2226 // begin undo-redo operation
2227 net->getViewNet()->getUndoList()->begin(originalContainer->getTagProperty().getGUIIcon(), "transform " + originalContainer->getTagStr() + " to " + toString(SUMO_TAG_CONTAINERFLOW));
2228 // create containerFlow
2229 routeHandler.buildContainerFlow(nullptr, containerParameters);
2230 // move all container plans to new container
2231 for (const auto& containerPlan : containerPlans) {
2232 containerPlan->setAttribute(GNE_ATTR_PARENT, "%dummyID%", net->getViewNet()->getUndoList());
2233 }
2234 // delete original container plan
2235 net->deleteDemandElement(originalContainer, net->getViewNet()->getUndoList());
2236 // restore ID of new container plan
2237 auto newContainer = net->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_CONTAINERFLOW, "%dummyID%");
2238 newContainer->setAttribute(SUMO_ATTR_ID, ID, net->getViewNet()->getUndoList());
2239 // enable attributes
2240 newContainer->enableAttribute(SUMO_ATTR_END, net->getViewNet()->getUndoList());
2241 newContainer->enableAttribute(SUMO_ATTR_CONTAINERSPERHOUR, net->getViewNet()->getUndoList());
2242 // finish undoList
2243 net->getViewNet()->getUndoList()->end();
2244 // check if inspect
2245 if (inspectAfterTransform) {
2246 // get created element
2247 auto transformedContainer = net->getAttributeCarriers()->retrieveDemandElement(containerParameters.tag, containerParameters.id);
2248 // inspect it
2249 net->getViewNet()->getViewParent()->getInspectorFrame()->inspectSingleElement(transformedContainer);
2250 }
2251}
2252
2253// ===========================================================================
2254// protected
2255// ===========================================================================
2256
2258GNERouteHandler::parseJunction(const SumoXMLTag tag, const std::string& junctionID) {
2259 GNEJunction* junction = myNet->getAttributeCarriers()->retrieveJunction(junctionID, false);
2260 // empty junctions aren't allowed. If junction is empty, write error, clear junctions and stop
2261 if (junction == nullptr) {
2262 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_JUNCTION)));
2263 }
2264 return junction;
2265}
2266
2267
2269GNERouteHandler::parseTAZ(const SumoXMLTag tag, const std::string& TAZID) {
2271 // empty TAZs aren't allowed. If TAZ is empty, write error, clear TAZs and stop
2272 if (TAZ == nullptr) {
2273 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_TAZ)));
2274 }
2275 return TAZ;
2276}
2277
2278
2279GNEEdge*
2280GNERouteHandler::parseEdge(const SumoXMLTag tag, const std::string& edgeID) {
2281 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2282 // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2283 if (edge == nullptr) {
2284 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2285 }
2286 return edge;
2287}
2288
2289
2290std::vector<GNEEdge*>
2291GNERouteHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
2292 std::vector<GNEEdge*> edges;
2293 for (const auto& edgeID : edgeIDs) {
2294 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2295 // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2296 if (edge == nullptr) {
2297 writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2298 edges.clear();
2299 return edges;
2300 } else {
2301 edges.push_back(edge);
2302 }
2303 }
2304 return edges;
2305}
2306
2307
2310 // check that sumoBaseObject has parent
2311 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2312 return nullptr;
2313 }
2314 if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSON) &&
2315 (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_PERSONFLOW)) {
2316 return nullptr;
2317 }
2318 // try it with person
2320 // if empty, try it with personFlow
2321 if (personParent == nullptr) {
2323 } else {
2324 return personParent;
2325 }
2326}
2327
2328
2331 // check that sumoBaseObject has parent
2332 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2333 return nullptr;
2334 }
2335 if ((sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINER) &&
2336 (sumoBaseObject->getParentSumoBaseObject()->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2337 return nullptr;
2338 }
2339 // try it with container
2341 // if empty, try it with containerFlow
2342 if (containerParent == nullptr) {
2344 } else {
2345 return containerParent;
2346 }
2347}
2348
2349
2350GNEEdge*
2352 if (obj->getParentSumoBaseObject() == nullptr) {
2353 // no parent defined
2354 return nullptr;
2355 }
2356 // get parent object
2358 // check person conditions
2359 if (person && (parentObject->getTag() != SUMO_TAG_PERSON) && (parentObject->getTag() != SUMO_TAG_PERSONFLOW)) {
2360 // invalid parent
2361 return nullptr;
2362 }
2363 // check container conditions
2364 if (!person && (parentObject->getTag() != SUMO_TAG_CONTAINER) && (parentObject->getTag() != SUMO_TAG_CONTAINERFLOW)) {
2365 // invalid parent
2366 return nullptr;
2367 }
2368 // search previous child
2369 const auto it = std::find(parentObject->getSumoBaseObjectChildren().begin(), parentObject->getSumoBaseObjectChildren().end(), obj);
2370 if (it == parentObject->getSumoBaseObjectChildren().begin()) {
2371 return nullptr;
2372 }
2373 // get last children
2374 const CommonXMLStructure::SumoBaseObject* previousPlan = *(it - 1);
2375 // check person conditions
2376 if (person && (previousPlan->getTag() != SUMO_TAG_WALK) && (previousPlan->getTag() != SUMO_TAG_RIDE) &&
2377 (previousPlan->getTag() != SUMO_TAG_PERSONTRIP) && (previousPlan->getTag() != SUMO_TAG_STOP)) {
2378 // invalid last child
2379 return nullptr;
2380 }
2381 // check container conditions
2382 if (!person && (previousPlan->getTag() != SUMO_TAG_TRANSPORT) && (previousPlan->getTag() != SUMO_TAG_TRANSHIP) &&
2383 (previousPlan->getTag() != SUMO_TAG_STOP)) {
2384 // invalid last child
2385 return nullptr;
2386 }
2387 // ends in an edge (only for stops)
2388 if (previousPlan->hasStringAttribute(SUMO_ATTR_EDGE)) {
2390 }
2391 // ends in a lane (only for stops)
2392 if (previousPlan->hasStringAttribute(SUMO_ATTR_LANE)) {
2393 const auto lane = myNet->getAttributeCarriers()->retrieveLane(previousPlan->getStringAttribute(SUMO_ATTR_LANE), false);
2394 if (lane) {
2395 return lane->getParentEdge();
2396 } else {
2397 return nullptr;
2398 }
2399 }
2400 // ends in a route (walk)
2401 if (previousPlan->hasStringAttribute(SUMO_ATTR_ROUTE) &&
2402 !previousPlan->getStringAttribute(SUMO_ATTR_ROUTE).empty()) {
2404 if (route) {
2405 return route->getParentEdges().back();
2406 } else {
2407 return nullptr;
2408 }
2409 }
2410 // ends in a list of edges (walk)
2411 if (previousPlan->hasStringListAttribute(SUMO_ATTR_EDGES) &&
2412 !previousPlan->getStringListAttribute(SUMO_ATTR_EDGES).empty()) {
2413 return myNet->getAttributeCarriers()->retrieveEdge(previousPlan->getStringListAttribute(SUMO_ATTR_EDGES).back(), false);
2414 }
2415 // ends in a "to" edge
2416 if (previousPlan->hasStringAttribute(SUMO_ATTR_TO) &&
2417 !previousPlan->getStringAttribute(SUMO_ATTR_TO).empty()) {
2418 return myNet->getAttributeCarriers()->retrieveEdge(previousPlan->getStringAttribute(SUMO_ATTR_TO), false);
2419 }
2420 // ends in a "busStop"
2421 if (previousPlan->hasStringAttribute(SUMO_ATTR_BUS_STOP) &&
2422 !previousPlan->getStringAttribute(SUMO_ATTR_BUS_STOP).empty()) {
2424 if (busStop) {
2425 return busStop->getParentLanes().front()->getParentEdge();
2426 } else {
2427 return nullptr;
2428 }
2429 }
2430 // ends in a "containerStop"
2431 if (previousPlan->hasStringAttribute(SUMO_ATTR_CONTAINER_STOP) &&
2432 !previousPlan->getStringAttribute(SUMO_ATTR_CONTAINER_STOP).empty()) {
2434 if (containerStop) {
2435 return containerStop->getParentLanes().front()->getParentEdge();
2436 } else {
2437 return nullptr;
2438 }
2439 }
2440 return nullptr;
2441}
2442
2443
2446 if (obj->getParentSumoBaseObject() == nullptr) {
2447 // no parent defined
2448 return nullptr;
2449 }
2450 // get parent object
2452 // search previous child
2453 const auto it = std::find(parentObject->getSumoBaseObjectChildren().begin(), parentObject->getSumoBaseObjectChildren().end(), obj);
2454 if (it == parentObject->getSumoBaseObjectChildren().begin()) {
2455 return nullptr;
2456 }
2457 // get last child
2458 const CommonXMLStructure::SumoBaseObject* previousPersonPlan = *(it - 1);
2459 // ends in an junction (only for stops)
2460 if (previousPersonPlan->hasStringAttribute(SUMO_ATTR_TOJUNCTION)) {
2462 }
2463 return nullptr;
2464}
2465
2466
2467bool
2469 // retrieve demand element
2470 auto demandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false);
2471 // if demand exist, check if overwrite (delete)
2472 if (demandElement) {
2473 if (myAllowUndoRedo == false) {
2474 // only overwrite if allow undo-redo
2475 return false;
2476 } else if (myOverwrite) {
2477 // update demand to overwrite
2478 myDemandToOverwrite = demandElement;
2479 return true;
2480 } else {
2481 // duplicated demand
2482 return false;
2483 }
2484 } else {
2485 // demand with these id doesn't exist, then all ok
2486 return true;
2487 }
2488}
2489
2490
2491void
2493 if (myDemandToOverwrite) {
2494 // remove element
2496 // reset pointer
2497 myDemandToOverwrite = nullptr;
2498 }
2499}
2500
2501/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ CONTAINERFLOW
@ VTYPEDISTRIBUTION
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:281
#define TL(string)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:288
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
const std::set< std::string > DEFAULT_VTYPES
const int STOP_DURATION_SET
@ GIVEN
The lane is given.
const int STOP_SPEED_SET
const int STOP_UNTIL_SET
@ GIVEN
The speed is given.
const int VEHPARS_DEPARTLANE_SET
const int STOP_END_SET
const int VEHPARS_DEPARTSPEED_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_TRIP_JUNCTIONS
a trip between junctions
@ GNE_TAG_TRIP_TAZS
a single trip definition that uses TAZs
@ GNE_TAG_PERSONTRIP_JUNCTIONS
@ GNE_TAG_WAYPOINT_PARKINGAREA
waypoint placed over a parking area
@ GNE_TAG_TRANSPORT_CONTAINERSTOP
@ 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
@ GNE_TAG_PERSONTRIP_BUSSTOP
@ SUMO_TAG_NOTHING
invalid tag
@ SUMO_TAG_TRANSHIP
@ GNE_TAG_WALK_EDGES
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ GNE_TAG_STOP_BUSSTOP
stop placed over a busStop
@ SUMO_TAG_CONTAINERFLOW
@ GNE_TAG_WAYPOINT_TRAINSTOP
waypoint placed over a busStop
@ GNE_TAG_WAYPOINT_CONTAINERSTOP
waypoint placed over a containerStop
@ GNE_TAG_STOPCONTAINER_EDGE
@ GNE_TAG_WAYPOINT_BUSSTOP
waypoint placed over a busStop
@ SUMO_TAG_BUS_STOP
A bus stop.
@ GNE_TAG_WAYPOINT_CHARGINGSTATION
waypoint placed over a charging station
@ GNE_TAG_STOPPERSON_BUSSTOP
@ SUMO_TAG_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
@ GNE_TAG_FLOW_JUNCTIONS
a flow between junctions
@ GNE_TAG_TRANSHIP_EDGES
@ GNE_TAG_STOP_CONTAINERSTOP
stop placed over a containerStop
@ GNE_TAG_STOPCONTAINER_CONTAINERSTOP
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_TRANSPORT
@ GNE_TAG_PERSONTRIP_TRAINSTOP
@ GNE_TAG_FLOW_TAZS
a flow between TAZs
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ GNE_TAG_WALK_BUSSTOP
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_RIDE
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ GNE_TAG_RIDE_EDGE
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ GNE_TAG_TRANSHIP_EDGE
@ GNE_TAG_WALK_JUNCTIONS
@ GNE_TAG_VEHICLE_WITHROUTE
description of a vehicle with an embedded route
@ GNE_TAG_WAYPOINT_LANE
waypoint placed over a lane
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONTRIP
@ GNE_TAG_WALK_TRAINSTOP
@ GNE_TAG_STOP_LANE
stop placed over a lane
@ GNE_TAG_STOPPERSON_TRAINSTOP
@ GNE_TAG_RIDE_TRAINSTOP
@ GNE_TAG_WALK_EDGE
@ GNE_TAG_STOP_TRAINSTOP
stop placed over a trainStop
@ GNE_TAG_STOP_CHARGINGSTATION
stop placed over a charging station
@ GNE_TAG_PERSONTRIP_EDGE
@ GNE_TAG_RIDE_BUSSTOP
@ GNE_TAG_STOPPERSON_EDGE
@ GNE_TAG_WALK_ROUTE
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ GNE_TAG_TRANSHIP_CONTAINERSTOP
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ GNE_TAG_TRANSPORT_EDGE
@ SUMO_ATTR_LINES
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_LANE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VIA
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_BUS_STOP
@ 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
@ GNE_ATTR_VTYPE_DISTRIBUTION
vehicle type distribution
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_MODES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_PROB
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_TOJUNCTION
@ 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 AbstractPoly the given coordinate.
Definition Boundary.cpp:172
const SUMOVehicleParameter::Stop & getStopParameter() const
get stop parameters
SUMOTime getTimeAttribute(const SumoXMLAttr attr) const
get time attribute
bool 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
bool hasDoubleAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given double attribute
void setVehicleParameter(const SUMOVehicleParameter *vehicleParameter)
set vehicle parameters
void addStringAttribute(const SumoXMLAttr attr, const std::string &value)
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
void getAttributesAndValues(CommonXMLStructure::SumoBaseObject *baseObject, bool includeAll) const
get attributes and their values
An Element which don't belong to GNENet but has influence in the simulation.
virtual double getAttributeDouble(SumoXMLAttr key) const =0
virtual void computePathElement()=0
compute pathElement
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
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:840
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< 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:118
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 element int GNENet 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:641
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:120
GNEPathManager * getPathManager()
get path manager
Definition GNENet.cpp:132
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2030
GNEAdditional * getToStoppingPlace(SumoXMLTag expectedTag) const
get to stoppingPlace
const std::vector< GNEJunction * > & getSelectedJunctions() const
get current selected junctions
const std::vector< GNEEdge * > & getSelectedEdges() const
get current selected edges
GNEDemandElement * getRoute() const
get route
const std::vector< Path > & getPath() const
get path route
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &partialEdges) const
calculate Dijkstra path between a list of partial edges
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
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
bool isContainerIdDuplicated(const std::string &id)
check if there is already a container (Container or ContainerFlow) with the given ID
const bool myOverwrite
check if overwrite
bool isVehicleIdDuplicated(const std::string &id)
check if there is already a vehicle (Vehicle, Trip, Flow or Flow) with the given ID
void buildContainerFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &containerFlowParameters)
build container flow
void buildRouteDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id)
build route distribution
bool checkDuplicatedDemandElement(const SumoXMLTag tag, const std::string &id)
check if given ID correspond to a duplicated demand element
CommonXMLStructure::SumoBaseObject * myPlanObject
pointer for person and container plans
GNEDemandElement * getPersonParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get person parent
GNEJunction * parseJunction(const SumoXMLTag tag, const std::string &junctionID)
parse junction
const bool myAllowUndoRedo
allow undo/redo
GNEEdge * getPreviousPlanEdge(const bool person, const CommonXMLStructure::SumoBaseObject *obj) const
get previos person/container plan edge
void overwriteDemandElement()
remove overwrited demand element
void buildPerson(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personParameters)
build person
static void transformToRouteFlow(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform routeFlow over an existent route
GNENet * myNet
pointer to GNENet
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 buildTransport(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &toEdgeID, const std::string &toBusStopID, const std::vector< std::string > &lines, const double arrivalPos)
build transport
static void transformToFlow(GNEVehicle *originalVehicle)
transform to flow
void buildTripTAZs(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromTAZID, const std::string &toTAZID)
build trip over TAZs
GNEEdge * parseEdge(const SumoXMLTag tag, const std::string &edgeID)
parse edge
void buildFlowOverRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters)
build a flow over an existent route
void buildTripJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build trip over junctions
GNEJunction * getPreviousPlanJunction(const bool person, const CommonXMLStructure::SumoBaseObject *obj) const
get previos person/container plan junction
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 Parameterised::Map &routeParameters)
build route
void buildFlowJunctions(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromJunctionID, const std::string &toJunctionID)
build flow over junctions
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
bool buildPersonPlan(SumoXMLTag tag, GNEDemandElement *personParent, GNEAttributesCreator *personPlanAttributes, GNEPathCreator *pathCreator, const bool centerAfterCreation)
build person plan
void buildTranship(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &toEdgeID, const std::string &toBusStopID, const std::vector< std::string > &edgeIDs, const double speed, const double departPosition, const double arrivalPosition)
build tranship
static void transformToTrip(GNEVehicle *originalVehicle)
transform to trip
bool buildContainerPlan(SumoXMLTag tag, GNEDemandElement *containerParent, GNEAttributesCreator *containerPlanAttributes, GNEPathCreator *pathCreator, const bool centerAfterCreation)
build container plan
void buildWalk(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &toEdgeID, const std::string &fromJunctionID, const std::string &toJunctionID, const std::string &toBusStopID, const std::string &toTrainStopID, const std::vector< std::string > &edgeIDs, const std::string &routeID, double arrivalPos)
build walk
static void transformToPerson(GNEPerson *originalPerson)
transform person functions
void buildFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameters, const std::string &fromEdgeID, const std::string &toEdgeIDs)
build flow
GNEAdditional * parseTAZ(const SumoXMLTag tag, const std::string &TAZID)
parse TAZ
virtual ~GNERouteHandler()
Destructor.
void buildEmbeddedRoute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::vector< std::string > &edgeIDs, const RGBColor &color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map &routeParameters)
build embedded route
void buildPersonFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &personFlowParameters)
build person flow
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::vector< std::string > &edgeIDs)
parse edges
void buildPersonTrip(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &toEdgeID, const std::string &fromJunctionID, const std::string &toJunctionID, const std::string &toBusStopID, const std::string &toTrainStopID, double arrivalPos, const std::vector< std::string > &types, const std::vector< std::string > &modes, const std::vector< std::string > &lines)
build person trip
void buildRide(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &fromEdgeID, const std::string &toEdgeID, const std::string &toBusStopID, const std::string &toTrainStopID, double arrivalPos, const std::vector< std::string > &lines)
build ride
GNEDemandElement * getContainerParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get container parent
void buildStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter::Stop &stopParameters)
build stop
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
GNEDemandElement * myDemandToOverwrite
demand to overwrite (using undor-redo
void buildVTypeDistribution(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const int deterministic, const std::vector< std::string > &vTypes)
build vType distribution
GNERouteHandler(const std::string &file, GNENet *net, const bool allowUndoRedo, const bool overwrite)
Constructor.
static void transformToVehicle(GNEVehicle *originalVehicle, bool createEmbeddedRoute)
transform vehicle functions
bool isContainer() const
return true if tag correspond to a container element
bool hasEmbeddedRoute() const
return true if tag correspond to an element that owns an embedded route
bool isVehicle() const
return true if tag correspond to a vehicle element
GUIIcon getGUIIcon() const
get GUI icon associated to this Tag
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isPerson() const
return true if tag correspond to a person element
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
GNETagSelector * getVehicleTagSelector() const
get vehicle tag selector (needed for transform vehicles)
SUMOVehicleClass getVClass() const
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
void setStatusBarText(const std::string &text)
set statusBar text
GNEVehicleFrame * getVehicleFrame() const
get frame for DEMAND_VEHICLE
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
Boundary getVisibleBoundary() const
get visible boundary
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
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 (used only in netedit)
std::string lane
The lane to stop at.
double speed
the speed at which this stop counts as reached (waypoint mode)
std::string parkingarea
(Optional) parking area if one is assigned to the stop
std::string chargingStation
(Optional) charging station if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
SUMOTime until
The time at which the vehicle may continue its journey.
std::string actType
act Type (only used by Persons) (used by netedit)
double endPos
The stopping position end.
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string containerstop
(Optional) container stop if one is assigned to the stop
SUMOTime duration
The stopping duration.
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double departSpeed
(optional) The initial speed of the vehicle
SumoXMLTag tag
The vehicle tag.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
bool wasSet(int what) const
Returns whether the given parameter was set.