Eclipse SUMO - Simulation of Urban MObility
GNEAdditionalHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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 trigger objects for netedit
19 /****************************************************************************/
20 #include <config.h>
21 #include <utils/xml/XMLSubSys.h>
24 #include <netedit/GNEViewNet.h>
25 #include <netedit/GNEUndoList.h>
26 #include <netedit/GNENet.h>
29 
30 #include "GNEAdditionalHandler.h"
31 #include "GNEBusStop.h"
32 #include "GNEAccess.h"
33 #include "GNECalibrator.h"
34 #include "GNECalibratorFlow.h"
35 #include "GNEChargingStation.h"
36 #include "GNEClosingLaneReroute.h"
37 #include "GNEClosingReroute.h"
38 #include "GNEContainerStop.h"
39 #include "GNEDestProbReroute.h"
40 #include "GNEDetectorE1.h"
41 #include "GNEDetectorE2.h"
42 #include "GNEDetectorE3.h"
43 #include "GNEDetectorEntryExit.h"
44 #include "GNEDetectorE1Instant.h"
45 #include "GNEParkingArea.h"
46 #include "GNEParkingSpace.h"
47 #include "GNERerouter.h"
48 #include "GNERerouterSymbol.h"
49 #include "GNERerouterInterval.h"
50 #include "GNERouteProbReroute.h"
51 #include "GNEParkingAreaReroute.h"
52 #include "GNERouteProbe.h"
53 #include "GNEVaporizer.h"
54 #include "GNEVariableSpeedSign.h"
57 #include "GNETAZ.h"
58 #include "GNETAZSourceSink.h"
59 
60 
61 // ===========================================================================
62 // GNEAdditionalHandler method definitions
63 // ===========================================================================
64 
65 GNEAdditionalHandler::GNEAdditionalHandler(const std::string& file, GNENet* net, GNEAdditional* additionalParent) :
66  ShapeHandler(file, *net->getAttributeCarriers()),
67  myNet(net) {
69  // check if we're loading values of another additionals (example: Rerouter values)
70  if (additionalParent) {
73  }
74  // define default values for shapes
76 }
77 
78 
80  delete myLastInsertedElement;
81 }
82 
83 
84 void
86  // Obtain tag of element
87  SumoXMLTag tag = static_cast<SumoXMLTag>(element);
88  // check if we're parsing a parameter
89  if (tag == SUMO_TAG_PARAM) {
90  // push element int stack
92  // parse parameter
93  parseParameter(attrs);
94  } else if (tag != SUMO_TAG_NOTHING) {
95  // push element int stack
96  if (tag == SUMO_TAG_TRAIN_STOP) {
97  // ensure that access elements can find their parent in myLastInsertedElement
98  tag = SUMO_TAG_BUS_STOP;
99  }
101  // Call parse and build depending of tag
102  switch (tag) {
103  case SUMO_TAG_POLY:
104  return parseAndBuildPoly(attrs);
105  case SUMO_TAG_POI:
106  return parseAndBuildPOI(attrs);
107  default:
108  // build additional
109  buildAdditional(myNet, true, tag, attrs, myLastInsertedElement);
110  }
111  }
112 }
113 
114 
115 void
117  // Obtain tag of element
118  SumoXMLTag tag = static_cast<SumoXMLTag>(element);
119  switch (tag) {
120  case SUMO_TAG_TAZ: {
122  if (TAZ != nullptr) {
123  if (TAZ->getTAZElementShape().size() == 0) {
124  Boundary b;
125  if (TAZ->getChildAdditionals().size() > 0) {
126  for (const auto& i : TAZ->getChildAdditionals()) {
127  b.add(i->getCenteringBoundary());
128  }
129  PositionVector boundaryShape;
130  boundaryShape.push_back(Position(b.xmin(), b.ymin()));
131  boundaryShape.push_back(Position(b.xmax(), b.ymin()));
132  boundaryShape.push_back(Position(b.xmax(), b.ymax()));
133  boundaryShape.push_back(Position(b.xmin(), b.ymax()));
134  boundaryShape.push_back(Position(b.xmin(), b.ymin()));
135  TAZ->setAttribute(SUMO_ATTR_SHAPE, toString(boundaryShape), myNet->getViewNet()->getUndoList());
136  }
137  }
138  }
139  break;
140  }
141  default:
142  break;
143  }
144  // pop last inserted element
146  // execute myEndElement of ShapeHandler (needed to update myLastParameterised)
148 }
149 
150 
151 Position
152 GNEAdditionalHandler::getLanePos(const std::string& poiID, const std::string& laneID, double lanePos, double lanePosLat) {
153  std::string edgeID;
154  int laneIndex;
155  NBHelpers::interpretLaneID(laneID, edgeID, laneIndex);
156  NBEdge* edge = myNet->retrieveEdge(edgeID)->getNBEdge();
157  if (edge == nullptr || laneIndex < 0 || edge->getNumLanes() <= laneIndex) {
158  WRITE_ERROR("Lane '" + laneID + "' to place poi '" + poiID + "' on is not known.");
159  return Position::INVALID;
160  }
161  if (lanePos < 0) {
162  lanePos = edge->getLength() + lanePos;
163  }
164  if (lanePos < 0 || lanePos > edge->getLength()) {
165  WRITE_WARNING("lane position " + toString(lanePos) + " for poi '" + poiID + "' is not valid.");
166  }
167  return edge->getLanes()[laneIndex].shape.positionAtOffset(lanePos, -lanePosLat);
168 }
169 
170 
171 bool
172 GNEAdditionalHandler::buildAdditional(GNENet* net, bool allowUndoRedo, SumoXMLTag tag, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
173  // Call parse and build depending of tag
174  switch (tag) {
175  case SUMO_TAG_BUS_STOP:
176  case SUMO_TAG_TRAIN_STOP:
177  return parseAndBuildBusStop(net, allowUndoRedo, attrs, insertedAdditionals);
178  case SUMO_TAG_ACCESS:
179  return parseAndBuildAccess(net, allowUndoRedo, attrs, insertedAdditionals);
181  return parseAndBuildContainerStop(net, allowUndoRedo, attrs, insertedAdditionals);
183  return parseAndBuildChargingStation(net, allowUndoRedo, attrs, insertedAdditionals);
184  case SUMO_TAG_E1DETECTOR:
186  return parseAndBuildDetectorE1(net, allowUndoRedo, attrs, insertedAdditionals);
187  case SUMO_TAG_E2DETECTOR:
190  return parseAndBuildDetectorE2(net, allowUndoRedo, attrs, insertedAdditionals);
191  case SUMO_TAG_E3DETECTOR:
193  return parseAndBuildDetectorE3(net, allowUndoRedo, attrs, insertedAdditionals);
194  case SUMO_TAG_DET_ENTRY:
195  return parseAndBuildDetectorEntry(net, allowUndoRedo, attrs, insertedAdditionals);
196  case SUMO_TAG_DET_EXIT:
197  return parseAndBuildDetectorExit(net, allowUndoRedo, attrs, insertedAdditionals);
199  return parseAndBuildDetectorE1Instant(net, allowUndoRedo, attrs, insertedAdditionals);
200  case SUMO_TAG_ROUTEPROBE:
201  return parseAndBuildRouteProbe(net, allowUndoRedo, attrs, insertedAdditionals);
202  case SUMO_TAG_VAPORIZER:
203  return parseAndBuildVaporizer(net, allowUndoRedo, attrs, insertedAdditionals);
204  case SUMO_TAG_TAZ:
205  return parseAndBuildTAZ(net, allowUndoRedo, attrs, insertedAdditionals);
206  case SUMO_TAG_TAZSOURCE:
207  return parseAndBuildTAZSource(net, allowUndoRedo, attrs, insertedAdditionals);
208  case SUMO_TAG_TAZSINK:
209  return parseAndBuildTAZSink(net, allowUndoRedo, attrs, insertedAdditionals);
210  case SUMO_TAG_VSS:
211  return parseAndBuildVariableSpeedSign(net, allowUndoRedo, attrs, insertedAdditionals);
212  case SUMO_TAG_STEP:
213  return parseAndBuildVariableSpeedSignStep(net, allowUndoRedo, attrs, insertedAdditionals);
214  case SUMO_TAG_CALIBRATOR:
216  return parseAndBuildCalibrator(net, allowUndoRedo, attrs, insertedAdditionals);
218  return parseAndBuildParkingArea(net, allowUndoRedo, attrs, insertedAdditionals);
220  return parseAndBuildParkingSpace(net, allowUndoRedo, attrs, insertedAdditionals);
222  return parseAndBuildCalibratorFlow(net, allowUndoRedo, attrs, insertedAdditionals);
223  case SUMO_TAG_REROUTER:
224  return parseAndBuildRerouter(net, allowUndoRedo, attrs, insertedAdditionals);
225  case SUMO_TAG_INTERVAL:
226  return parseAndBuildRerouterInterval(net, allowUndoRedo, attrs, insertedAdditionals);
228  return parseAndBuildRerouterClosingLaneReroute(net, allowUndoRedo, attrs, insertedAdditionals);
230  return parseAndBuildRerouterClosingReroute(net, allowUndoRedo, attrs, insertedAdditionals);
232  return parseAndBuildRerouterDestProbReroute(net, allowUndoRedo, attrs, insertedAdditionals);
234  return parseAndBuildRerouterParkingAreaReroute(net, allowUndoRedo, attrs, insertedAdditionals);
236  return parseAndBuildRerouterRouteProbReroute(net, allowUndoRedo, attrs, insertedAdditionals);
237  default:
238  return false;
239  }
240 }
241 
242 
244 GNEAdditionalHandler::buildBusStop(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane,
245  const double startPos, const double endPos, const int parametersSet,
246  const std::string& name, const std::vector<std::string>& lines, int personCapacity, double parkingLength,
247  bool friendlyPosition, bool blockMovement) {
248  if (net->retrieveAdditional(SUMO_TAG_BUS_STOP, id, false) == nullptr) {
249  GNEAdditional* busStop = new GNEBusStop(id, lane, net, startPos, endPos, parametersSet, name, lines, personCapacity, parkingLength, friendlyPosition, blockMovement);
250  if (allowUndoRedo) {
252  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(busStop, true), true);
253  net->getViewNet()->getUndoList()->p_end();
254  } else {
255  net->getAttributeCarriers()->insertAdditional(busStop);
256  lane->addChildElement(busStop);
257  busStop->incRef("buildBusStop");
258  }
259  return busStop;
260  } else {
261  throw ProcessError("Could not build " + toString(SUMO_TAG_BUS_STOP) + " with ID '" + id + "' in netedit; probably declared twice.");
262  }
263 }
264 
265 
267 GNEAdditionalHandler::buildAccess(GNENet* net, bool allowUndoRedo, GNEAdditional* busStop, GNELane* lane, double pos, const std::string& length, bool friendlyPos, bool blockMovement) {
268  // Check if busStop parent and lane is correct
269  if (lane == nullptr) {
270  throw ProcessError("Could not build " + toString(SUMO_TAG_ACCESS) + " in netedit; " + toString(SUMO_TAG_LANE) + " doesn't exist.");
271  } else if (busStop == nullptr) {
272  throw ProcessError("Could not build " + toString(SUMO_TAG_ACCESS) + " in netedit; " + toString(SUMO_TAG_BUS_STOP) + " parent doesn't exist.");
273  } else if (!accessCanBeCreated(busStop, lane->getParentEdge())) {
274  throw ProcessError("Could not build " + toString(SUMO_TAG_ACCESS) + " in netedit; " + toString(SUMO_TAG_BUS_STOP) + " parent already owns a Acces in the edge '" + lane->getParentEdge()->getID() + "'");
275  } else {
276  GNEAdditional* access = new GNEAccess(busStop, lane, net, pos, length, friendlyPos, blockMovement);
277  if (allowUndoRedo) {
278  net->getViewNet()->getUndoList()->p_begin("add " + toString(SUMO_TAG_ACCESS));
279  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(access, true), true);
280  net->getViewNet()->getUndoList()->p_end();
281  } else {
282  net->getAttributeCarriers()->insertAdditional(access);
283  lane->addChildElement(access);
284  busStop->addChildElement(access);
285  access->incRef("buildAccess");
286  }
287  return access;
288  }
289 }
290 
291 
293 GNEAdditionalHandler::buildContainerStop(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, const double startPos, const double endPos, const int parametersSet,
294  const std::string& name, const std::vector<std::string>& lines, bool friendlyPosition, bool blockMovement) {
295  if (net->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, id, false) == nullptr) {
296  GNEAdditional* containerStop = new GNEContainerStop(id, lane, net, startPos, endPos, parametersSet, name, lines, friendlyPosition, blockMovement);
297  if (allowUndoRedo) {
299  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(containerStop, true), true);
300  net->getViewNet()->getUndoList()->p_end();
301  } else {
302  net->getAttributeCarriers()->insertAdditional(containerStop);
303  lane->addChildElement(containerStop);
304  containerStop->incRef("buildContainerStop");
305  }
306  return containerStop;
307  } else {
308  throw ProcessError("Could not build " + toString(SUMO_TAG_CONTAINER_STOP) + " with ID '" + id + "' in netedit; probably declared twice.");
309  }
310 }
311 
312 
314 GNEAdditionalHandler::buildChargingStation(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, const double startPos, const double endPos, const int parametersSet,
315  const std::string& name, double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay, bool friendlyPosition, bool blockMovement) {
316  if (net->retrieveAdditional(SUMO_TAG_CHARGING_STATION, id, false) == nullptr) {
317  GNEAdditional* chargingStation = new GNEChargingStation(id, lane, net, startPos, endPos, parametersSet, name, chargingPower, efficiency, chargeInTransit, chargeDelay, friendlyPosition, blockMovement);
318  if (allowUndoRedo) {
320  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(chargingStation, true), true);
321  net->getViewNet()->getUndoList()->p_end();
322  } else {
323  net->getAttributeCarriers()->insertAdditional(chargingStation);
324  lane->addChildElement(chargingStation);
325  chargingStation->incRef("buildChargingStation");
326  }
327  return chargingStation;
328  } else {
329  throw ProcessError("Could not build " + toString(SUMO_TAG_CHARGING_STATION) + " with ID '" + id + "' in netedit; probably declared twice.");
330  }
331 }
332 
333 
335 GNEAdditionalHandler::buildParkingArea(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, const double startPos, const double endPos, const int parametersSet,
336  const std::string& name, bool friendlyPosition, int roadSideCapacity, bool onRoad, double width, const std::string& length, double angle, bool blockMovement) {
337  if (net->retrieveAdditional(SUMO_TAG_PARKING_AREA, id, false) == nullptr) {
338  GNEAdditional* parkingArea = new GNEParkingArea(id, lane, net, startPos, endPos, parametersSet, name, friendlyPosition, roadSideCapacity, onRoad, width, length, angle, blockMovement);
339  if (allowUndoRedo) {
341  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingArea, true), true);
342  net->getViewNet()->getUndoList()->p_end();
343  } else {
344  net->getAttributeCarriers()->insertAdditional(parkingArea);
345  lane->addChildElement(parkingArea);
346  parkingArea->incRef("buildParkingArea");
347  }
348  return parkingArea;
349  } else {
350  throw ProcessError("Could not build " + toString(SUMO_TAG_PARKING_AREA) + " with ID '" + id + "' in netedit; probably declared twice.");
351  }
352 }
353 
354 
356 GNEAdditionalHandler::buildParkingSpace(GNENet* net, bool allowUndoRedo, GNEAdditional* parkingAreaParent, Position pos, double width, double length, double angle, bool blockMovement) {
357  GNEAdditional* parkingSpace = new GNEParkingSpace(net, parkingAreaParent, pos, width, length, angle, blockMovement);
358  if (allowUndoRedo) {
360  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingSpace, true), true);
361  net->getViewNet()->getUndoList()->p_end();
362  } else {
363  net->getAttributeCarriers()->insertAdditional(parkingSpace);
364  parkingAreaParent->addChildElement(parkingSpace);
365  parkingSpace->incRef("buildParkingSpace");
366  }
367  // update geometry (due boundaries)
368  parkingSpace->updateGeometry();
369  return parkingSpace;
370 }
371 
372 
374 GNEAdditionalHandler::buildDetectorE1(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, double pos, SUMOTime freq, const std::string& filename, const std::string& vehicleTypes, const std::string& name, bool friendlyPos, bool blockMovement) {
375  if (net->retrieveAdditional(SUMO_TAG_E1DETECTOR, id, false) == nullptr) {
376  GNEAdditional* detectorE1 = new GNEDetectorE1(id, lane, net, pos, freq, filename, vehicleTypes, name, friendlyPos, blockMovement);
377  if (allowUndoRedo) {
379  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1, true), true);
380  net->getViewNet()->getUndoList()->p_end();
381  } else {
382  net->getAttributeCarriers()->insertAdditional(detectorE1);
383  lane->addChildElement(detectorE1);
384  detectorE1->incRef("buildDetectorE1");
385  }
386  return detectorE1;
387  } else {
388  throw ProcessError("Could not build " + toString(SUMO_TAG_E1DETECTOR) + " with ID '" + id + "' in netedit; probably declared twice.");
389  }
390 }
391 
392 
394 GNEAdditionalHandler::buildSingleLaneDetectorE2(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, double pos, double length, const std::string& freq, const std::string& trafficLight,
395  const std::string& filename, const std::string& vehicleTypes, const std::string& name, SUMOTime timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos, bool blockMovement) {
396  if (net->retrieveAdditional(SUMO_TAG_E2DETECTOR, id, false) == nullptr) {
397  GNEAdditional* detectorE2 = new GNEDetectorE2(id, lane, net, pos, length, freq, trafficLight, filename, vehicleTypes, name, timeThreshold, speedThreshold, jamThreshold, friendlyPos, blockMovement);
398  if (allowUndoRedo) {
400  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
401  net->getViewNet()->getUndoList()->p_end();
402  } else {
403  net->getAttributeCarriers()->insertAdditional(detectorE2);
404  lane->addChildElement(detectorE2);
405  detectorE2->incRef("buildDetectorE2");
406  }
407  return detectorE2;
408  } else {
409  throw ProcessError("Could not build " + toString(SUMO_TAG_E2DETECTOR) + " with ID '" + id + "' in netedit; probably declared twice.");
410  }
411 }
412 
413 
415 GNEAdditionalHandler::buildMultiLaneDetectorE2(GNENet* net, bool allowUndoRedo, const std::string& id, const std::vector<GNELane*>& lanes, double pos, double endPos, const std::string& freq, const std::string& trafficLight,
416  const std::string& filename, const std::string& vehicleTypes, const std::string& name, SUMOTime timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos, bool blockMovement) {
417  if (net->retrieveAdditional(SUMO_TAG_E2DETECTOR_MULTILANE, id, false) == nullptr) {
418  GNEDetectorE2* detectorE2 = new GNEDetectorE2(id, lanes, net, pos, endPos, freq, trafficLight, filename, vehicleTypes, name, timeThreshold, speedThreshold, jamThreshold, friendlyPos, blockMovement);
419  if (allowUndoRedo) {
421  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
422  net->getViewNet()->getUndoList()->p_end();
423  } else {
424  net->getAttributeCarriers()->insertAdditional(detectorE2);
425  // use to avoid LNK2019
426  GNEAdditional* detectorE2Additional = detectorE2;
427  for (const auto& lane : lanes) {
428  lane->addChildElement(detectorE2Additional);
429  }
430  detectorE2->incRef("buildDetectorE2Multilane");
431  }
432  return detectorE2;
433  } else {
434  throw ProcessError("Could not build " + toString(SUMO_TAG_E2DETECTOR_MULTILANE) + " with ID '" + id + "' in netedit; probably declared twice.");
435  }
436 }
437 
438 
440 GNEAdditionalHandler::buildDetectorE3(GNENet* net, bool allowUndoRedo, const std::string& id, Position pos, SUMOTime freq, const std::string& filename, const std::string& vehicleTypes,
441  const std::string& name, SUMOTime timeThreshold, double speedThreshold, bool blockMovement) {
442  if (net->retrieveAdditional(SUMO_TAG_E3DETECTOR, id, false) == nullptr) {
443  GNEAdditional* detectorE3 = new GNEDetectorE3(id, net, pos, freq, filename, vehicleTypes, name, timeThreshold, speedThreshold, blockMovement);
444  if (allowUndoRedo) {
446  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE3, true), true);
447  net->getViewNet()->getUndoList()->p_end();
448  } else {
449  net->getAttributeCarriers()->insertAdditional(detectorE3);
450  detectorE3->incRef("buildDetectorE3");
451  }
452  return detectorE3;
453  } else {
454  throw ProcessError("Could not build " + toString(SUMO_TAG_E3DETECTOR) + " with ID '" + id + "' in netedit; probably declared twice.");
455  }
456 }
457 
458 
460 GNEAdditionalHandler::buildDetectorEntry(GNENet* net, bool allowUndoRedo, GNEAdditional* E3Parent, GNELane* lane, double pos, bool friendlyPos, bool blockMovement) {
461  // Check if Detector E3 parent and lane is correct
462  if (lane == nullptr) {
463  throw ProcessError("Could not build " + toString(SUMO_TAG_DET_ENTRY) + " in netedit; " + toString(SUMO_TAG_LANE) + " doesn't exist.");
464  } else if (E3Parent == nullptr) {
465  throw ProcessError("Could not build " + toString(SUMO_TAG_DET_ENTRY) + " in netedit; " + toString(SUMO_TAG_E3DETECTOR) + " parent doesn't exist.");
466  } else {
467  GNEAdditional* entry = new GNEDetectorEntryExit(SUMO_TAG_DET_ENTRY, net, E3Parent, lane, pos, friendlyPos, blockMovement);
468  if (allowUndoRedo) {
470  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(entry, true), true);
471  net->getViewNet()->getUndoList()->p_end();
472  } else {
473  net->getAttributeCarriers()->insertAdditional(entry);
474  lane->addChildElement(entry);
475  E3Parent->addChildElement(entry);
476  entry->incRef("buildDetectorEntry");
477  }
478  return entry;
479  }
480 }
481 
482 
484 GNEAdditionalHandler::buildDetectorExit(GNENet* net, bool allowUndoRedo, GNEAdditional* E3Parent, GNELane* lane, double pos, bool friendlyPos, bool blockMovement) {
485  // Check if Detector E3 parent and lane is correct
486  if (lane == nullptr) {
487  throw ProcessError("Could not build " + toString(SUMO_TAG_DET_EXIT) + " in netedit; " + toString(SUMO_TAG_LANE) + " doesn't exist.");
488  } else if (E3Parent == nullptr) {
489  throw ProcessError("Could not build " + toString(SUMO_TAG_DET_EXIT) + " in netedit; " + toString(SUMO_TAG_E3DETECTOR) + " parent doesn't exist.");
490  } else {
491  GNEAdditional* exit = new GNEDetectorEntryExit(SUMO_TAG_DET_EXIT, net, E3Parent, lane, pos, friendlyPos, blockMovement);
492  if (allowUndoRedo) {
494  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(exit, true), true);
495  net->getViewNet()->getUndoList()->p_end();
496  } else {
498  lane->addChildElement(exit);
499  E3Parent->addChildElement(exit);
500  exit->incRef("buildDetectorExit");
501  }
502  return exit;
503  }
504 }
505 
506 
508 GNEAdditionalHandler::buildDetectorE1Instant(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, double pos, const std::string& filename, const std::string& vehicleTypes, const std::string& name, bool friendlyPos, bool blockMovement) {
509  if (net->retrieveAdditional(SUMO_TAG_INSTANT_INDUCTION_LOOP, id, false) == nullptr) {
510  GNEAdditional* detectorE1Instant = new GNEDetectorE1Instant(id, lane, net, pos, filename, vehicleTypes, name, friendlyPos, blockMovement);
511  if (allowUndoRedo) {
513  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1Instant, true), true);
514  net->getViewNet()->getUndoList()->p_end();
515  } else {
516  net->getAttributeCarriers()->insertAdditional(detectorE1Instant);
517  lane->addChildElement(detectorE1Instant);
518  detectorE1Instant->incRef("buildDetectorE1Instant");
519  }
520  return detectorE1Instant;
521  } else {
522  throw ProcessError("Could not build " + toString(SUMO_TAG_INSTANT_INDUCTION_LOOP) + " with ID '" + id + "' in netedit; probably declared twice.");
523  }
524 }
525 
526 
528 GNEAdditionalHandler::buildCalibrator(GNENet* net, bool allowUndoRedo, const std::string& id, GNELane* lane, double pos, const std::string& name, const std::string& outfile, const SUMOTime freq, const std::string& routeprobe, bool centerAfterCreation) {
529  if (net->retrieveAdditional(SUMO_TAG_CALIBRATOR, id, false) == nullptr) {
530  GNEAdditional* calibrator = new GNECalibrator(id, net, lane, pos, freq, name, outfile, routeprobe);
531  if (allowUndoRedo) {
533  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
534  net->getViewNet()->getUndoList()->p_end();
535  // center after creation
536  if (centerAfterCreation) {
537  net->getViewNet()->centerTo(calibrator->getPositionInView(), false);
538  }
539  } else {
540  net->getAttributeCarriers()->insertAdditional(calibrator);
541  lane->addChildElement(calibrator);
542  calibrator->incRef("buildCalibrator");
543  }
544  return calibrator;
545  } else {
546  throw ProcessError("Could not build " + toString(SUMO_TAG_CALIBRATOR) + " with ID '" + id + "' in netedit; probably declared twice.");
547  }
548 }
549 
550 
552 GNEAdditionalHandler::buildCalibrator(GNENet* net, bool allowUndoRedo, const std::string& id, GNEEdge* edge, double pos, const std::string& name, const std::string& outfile, const SUMOTime freq, const std::string& routeprobe, bool centerAfterCreation) {
553  if (net->retrieveAdditional(SUMO_TAG_CALIBRATOR, id, false) == nullptr) {
554  GNEAdditional* calibrator = new GNECalibrator(id, net, edge, pos, freq, name, outfile, routeprobe);
555  if (allowUndoRedo) {
557  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
558  net->getViewNet()->getUndoList()->p_end();
559  // center after creation
560  if (centerAfterCreation) {
561  net->getViewNet()->centerTo(calibrator->getPositionInView(), false);
562  }
563  } else {
564  net->getAttributeCarriers()->insertAdditional(calibrator);
565  edge->addChildElement(calibrator);
566  calibrator->incRef("buildCalibrator");
567  }
568  return calibrator;
569  } else {
570  throw ProcessError("Could not build " + toString(SUMO_TAG_CALIBRATOR) + " with ID '" + id + "' in netedit; probably declared twice.");
571  }
572 }
573 
574 
576 GNEAdditionalHandler::buildCalibratorFlow(GNENet* net, bool allowUndoRedo, GNEAdditional* calibratorParent, GNEDemandElement* route, GNEDemandElement* vType,
577  const std::string& vehsPerHour, const std::string& speed, const RGBColor& color, const std::string& departLane, const std::string& departPos,
578  const std::string& departSpeed, const std::string& arrivalLane, const std::string& arrivalPos, const std::string& arrivalSpeed, const std::string& line,
579  int personNumber, int containerNumber, bool reroute, const std::string& departPosLat, const std::string& arrivalPosLat, SUMOTime begin, SUMOTime end) {
580 
581  // create Flow and add it to calibrator parent
582  GNEAdditional* flow = new GNECalibratorFlow(calibratorParent, vType, route, vehsPerHour, speed, color, departLane, departPos, departSpeed,
583  arrivalLane, arrivalPos, arrivalSpeed, line, personNumber, containerNumber, reroute,
584  departPosLat, arrivalPosLat, begin, end);
585  if (allowUndoRedo) {
586  net->getViewNet()->getUndoList()->p_begin("add " + flow->getTagStr());
587  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(flow, true), true);
588  net->getViewNet()->getUndoList()->p_end();
589  } else {
590  calibratorParent->addChildElement(flow);
591  flow->incRef("buildCalibratorFlow");
592  }
593  return flow;
594 }
595 
596 
598 GNEAdditionalHandler::buildRerouter(GNENet* net, bool allowUndoRedo, const std::string& id, Position pos, const std::vector<GNEEdge*>& edges, double prob, const std::string& name, const std::string& file, bool off, SUMOTime timeThreshold, const std::string& vTypes, bool blockMovement) {
599  if (net->retrieveAdditional(SUMO_TAG_REROUTER, id, false) == nullptr) {
600  // create reroute
601  GNEAdditional* rerouter = new GNERerouter(id, net, pos, name, file, prob, off, timeThreshold, vTypes, blockMovement);
602  // create rerouter Symbols
603  std::vector<GNEAdditional*> rerouterSymbols;
604  for (const auto& edge : edges) {
605  rerouterSymbols.push_back(new GNERerouterSymbol(rerouter, edge));
606  }
607  if (allowUndoRedo) {
609  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouter, true), true);
610  for (const auto& rerouterSymbol : rerouterSymbols) {
611  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterSymbol, true), true);
612  }
613  net->getViewNet()->getUndoList()->p_end();
614  } else {
615  net->getAttributeCarriers()->insertAdditional(rerouter);
616  // add symbols
617  for (int i = 0; i < (int)edges.size(); i++) {
618  edges.at(i)->addChildElement(rerouterSymbols.at(i));
619  rerouterSymbols.at(i)->incRef("buildRerouterSymbol");
620  }
621  rerouter->incRef("buildRerouter");
622  }
623  // parse rerouter children
624  if (!file.empty()) {
625  // we assume that rerouter values files is placed in the same folder as the additional file
626  std::string currentAdditionalFilename = FileHelpers::getFilePath(OptionsCont::getOptions().getString("additional-files"));
627  // Create additional handler for parse rerouter values
628  GNEAdditionalHandler rerouterValuesHandler(currentAdditionalFilename + file, net, rerouter);
629  // disable validation for rerouters
630  XMLSubSys::setValidation("never", "auto", "auto");
631  // Run parser
632  if (!XMLSubSys::runParser(rerouterValuesHandler, currentAdditionalFilename + file, false)) {
633  WRITE_MESSAGE("Loading of " + file + " failed.");
634  }
635  // enable validation for rerouters
636  XMLSubSys::setValidation("auto", "auto", "auto");
637  }
638  return rerouter;
639  } else {
640  throw ProcessError("Could not build " + toString(SUMO_TAG_REROUTER) + " with ID '" + id + "' in netedit; probably declared twice.");
641  }
642 }
643 
644 
646 GNEAdditionalHandler::buildRerouterInterval(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterParent, SUMOTime begin, SUMOTime end) {
647  // check if new interval will produce a overlapping
648  if (checkOverlappingRerouterIntervals(rerouterParent, begin, end)) {
649  // create rerouter interval and add it into rerouter parent
650  GNEAdditional* rerouterInterval = new GNERerouterInterval(rerouterParent, begin, end);
651  if (allowUndoRedo) {
652  net->getViewNet()->getUndoList()->p_begin("add " + rerouterInterval->getTagStr());
653  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterInterval, true), true);
654  net->getViewNet()->getUndoList()->p_end();
655  } else {
656  rerouterParent->addChildElement(rerouterInterval);
657  rerouterInterval->incRef("buildRerouterInterval");
658  }
659  return rerouterInterval;
660  } else {
661  throw ProcessError("Could not build " + toString(SUMO_TAG_INTERVAL) + " with begin '" + toString(begin) + "' and '" + toString(end) + "' in '" + rerouterParent->getID() + "' due overlapping.");
662  }
663 }
664 
665 
667 GNEAdditionalHandler::buildClosingLaneReroute(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterIntervalParent, GNELane* closedLane, SVCPermissions permissions) {
668  // create closing lane reorute
669  GNEAdditional* closingLaneReroute = new GNEClosingLaneReroute(rerouterIntervalParent, closedLane, permissions);
670  // add it to interval parent depending of allowUndoRedo
671  if (allowUndoRedo) {
672  net->getViewNet()->getUndoList()->p_begin("add " + closingLaneReroute->getTagStr());
673  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingLaneReroute, true), true);
674  net->getViewNet()->getUndoList()->p_end();
675  } else {
676  rerouterIntervalParent->addChildElement(closingLaneReroute);
677  closingLaneReroute->incRef("buildClosingLaneReroute");
678  }
679  return closingLaneReroute;
680 }
681 
682 
684 GNEAdditionalHandler::buildClosingReroute(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterIntervalParent, GNEEdge* closedEdge, SVCPermissions permissions) {
685  // create closing reroute
686  GNEAdditional* closingReroute = new GNEClosingReroute(rerouterIntervalParent, closedEdge, permissions);
687  // add it to interval parent depending of allowUndoRedo
688  if (allowUndoRedo) {
689  net->getViewNet()->getUndoList()->p_begin("add " + closingReroute->getTagStr());
690  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingReroute, true), true);
691  net->getViewNet()->getUndoList()->p_end();
692  } else {
693  rerouterIntervalParent->addChildElement(closingReroute);
694  closingReroute->incRef("buildClosingReroute");
695  }
696  return closingReroute;
697 }
698 
699 
701 GNEAdditionalHandler::builDestProbReroute(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterIntervalParent, GNEEdge* newEdgeDestination, double probability) {
702  // create dest probability reroute
703  GNEAdditional* destProbReroute = new GNEDestProbReroute(rerouterIntervalParent, newEdgeDestination, probability);
704  // add it to interval parent depending of allowUndoRedo
705  if (allowUndoRedo) {
706  net->getViewNet()->getUndoList()->p_begin("add " + destProbReroute->getTagStr());
707  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(destProbReroute, true), true);
708  net->getViewNet()->getUndoList()->p_end();
709  } else {
710  rerouterIntervalParent->addChildElement(destProbReroute);
711  destProbReroute->incRef("builDestProbReroute");
712  }
713  return destProbReroute;
714 }
715 
716 
718 GNEAdditionalHandler::builParkingAreaReroute(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterIntervalParent, GNEAdditional* newParkingArea, double probability, bool visible) {
719  // create dest probability reroute
720  GNEAdditional* parkingAreaReroute = new GNEParkingAreaReroute(rerouterIntervalParent, newParkingArea, probability, visible);
721  // add it to interval parent depending of allowUndoRedo
722  if (allowUndoRedo) {
723  net->getViewNet()->getUndoList()->p_begin("add " + parkingAreaReroute->getTagStr());
724  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingAreaReroute, true), true);
725  net->getViewNet()->getUndoList()->p_end();
726  } else {
727  rerouterIntervalParent->addChildElement(parkingAreaReroute);
728  parkingAreaReroute->incRef("builParkingAreaReroute");
729  }
730  return parkingAreaReroute;
731 }
732 
733 
735 GNEAdditionalHandler::buildRouteProbReroute(GNENet* net, bool allowUndoRedo, GNEAdditional* rerouterIntervalParent, const std::string& newRouteId, double probability) {
736  // create rout prob rereoute
737  GNEAdditional* routeProbReroute = new GNERouteProbReroute(rerouterIntervalParent, newRouteId, probability);
738  // add it to interval parent depending of allowUndoRedo
739  if (allowUndoRedo) {
740  net->getViewNet()->getUndoList()->p_begin("add " + routeProbReroute->getTagStr());
741  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbReroute, true), true);
742  net->getViewNet()->getUndoList()->p_end();
743  } else {
744  rerouterIntervalParent->addChildElement(routeProbReroute);
745  routeProbReroute->incRef("buildRouteProbReroute");
746  }
747  return routeProbReroute;
748 }
749 
750 
752 GNEAdditionalHandler::buildRouteProbe(GNENet* net, bool allowUndoRedo, const std::string& id, GNEEdge* edge, const std::string& freq, const std::string& name, const std::string& file, SUMOTime begin, bool centerAfterCreation) {
753  if (net->retrieveAdditional(SUMO_TAG_ROUTEPROBE, id, false) == nullptr) {
754  GNEAdditional* routeProbe = new GNERouteProbe(id, net, edge, freq, name, file, begin);
755  if (allowUndoRedo) {
757  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbe, true), true);
758  net->getViewNet()->getUndoList()->p_end();
759  // center after creation
760  if (centerAfterCreation) {
761  net->getViewNet()->centerTo(routeProbe->getPositionInView(), false);
762  }
763  } else {
764  net->getAttributeCarriers()->insertAdditional(routeProbe);
765  edge->addChildElement(routeProbe);
766  routeProbe->incRef("buildRouteProbe");
767  }
768  return routeProbe;
769  } else {
770  throw ProcessError("Could not build " + toString(SUMO_TAG_ROUTEPROBE) + " with ID '" + id + "' in netedit; probably declared twice.");
771  }
772 }
773 
774 
776 GNEAdditionalHandler::buildVariableSpeedSign(GNENet* net, bool allowUndoRedo, const std::string& id, Position pos, const std::vector<GNELane*>& lanes, const std::string& name, bool blockMovement) {
777  if (net->retrieveAdditional(SUMO_TAG_VSS, id, false) == nullptr) {
778  // create VSS
779  GNEAdditional* variableSpeedSign = new GNEVariableSpeedSign(id, net, pos, name, blockMovement);
780  // create VSS Symbols
781  std::vector<GNEAdditional*> VSSSymbols;
782  for (const auto& lane : lanes) {
783  VSSSymbols.push_back(new GNEVariableSpeedSignSymbol(variableSpeedSign, lane));
784  }
785  if (allowUndoRedo) {
786  net->getViewNet()->getUndoList()->p_begin("add " + toString(SUMO_TAG_VSS));
787  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSign, true), true);
788  for (const auto& VSSSymbol : VSSSymbols) {
789  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(VSSSymbol, true), true);
790  }
791  net->getViewNet()->getUndoList()->p_end();
792  } else {
793  net->getAttributeCarriers()->insertAdditional(variableSpeedSign);
794  // add symbols
795  for (int i = 0; i < (int)lanes.size(); i++) {
796  lanes.at(i)->addChildElement(VSSSymbols.at(i));
797  VSSSymbols.at(i)->incRef("buildVariableSpeedSignSymbol");
798  }
799  variableSpeedSign->incRef("buildVariableSpeedSign");
800  }
801  return variableSpeedSign;
802  } else {
803  throw ProcessError("Could not build " + toString(SUMO_TAG_VSS) + " with ID '" + id + "' in netedit; probably declared twice.");
804  }
805 }
806 
807 
809 GNEAdditionalHandler::buildVariableSpeedSignStep(GNENet* net, bool allowUndoRedo, GNEAdditional* VSSParent, double time, double speed) {
810  // create Variable Speed Sign
811  GNEAdditional* variableSpeedSignStep = new GNEVariableSpeedSignStep(VSSParent, time, speed);
812  // add it depending of allow undoRedo
813  if (allowUndoRedo) {
814  net->getViewNet()->getUndoList()->p_begin("add " + variableSpeedSignStep->getTagStr());
815  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSignStep, true), true);
816  net->getViewNet()->getUndoList()->p_end();
817  } else {
818  VSSParent->addChildElement(variableSpeedSignStep);
819  variableSpeedSignStep->incRef("buildVariableSpeedSignStep");
820  }
821  return variableSpeedSignStep;
822 }
823 
824 
826 GNEAdditionalHandler::buildVaporizer(GNENet* net, bool allowUndoRedo, GNEEdge* edge, SUMOTime startTime, SUMOTime endTime, const std::string& name, bool centerAfterCreation) {
827  GNEAdditional* vaporizer = new GNEVaporizer(net, edge, startTime, endTime, name);
828  if (allowUndoRedo) {
830  net->getViewNet()->getUndoList()->add(new GNEChange_Additional(vaporizer, true), true);
831  net->getViewNet()->getUndoList()->p_end();
832  // center after creation
833  if (centerAfterCreation) {
834  net->getViewNet()->centerTo(vaporizer->getPositionInView(), false);
835  }
836  } else {
837  net->getAttributeCarriers()->insertAdditional(vaporizer);
838  edge->addChildElement(vaporizer);
839  vaporizer->incRef("buildVaporizer");
840  }
841  return vaporizer;
842 }
843 
844 
846 GNEAdditionalHandler::buildTAZ(GNENet* net, bool allowUndoRedo, const std::string& id, const PositionVector& shape, const RGBColor& color, const std::vector<GNEEdge*>& edges, bool blockMovement) {
847  GNETAZElement* TAZ = new GNETAZ(id, net, shape, color, blockMovement);
848  // disable updating geometry of TAZ children during insertion (because in large nets provokes slowdowns)
849  net->disableUpdateGeometry();
850  if (allowUndoRedo) {
851  net->getViewNet()->getUndoList()->p_begin("add " + toString(SUMO_TAG_TAZ));
852  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZ, true), true);
853  // create TAZEdges
854  for (const auto& edge : edges) {
855  // create TAZ Source using GNEChange_Additional
856  GNETAZElement* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
857  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSource, true), true);
858  // create TAZ Sink using GNEChange_Additional
859  GNETAZElement* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
860  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSink, true), true);
861  }
862  net->getViewNet()->getUndoList()->p_end();
863  } else {
865  TAZ->incRef("buildTAZ");
866  for (const auto& edge : edges) {
867  // create TAZ Source
868  GNETAZElement* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
869  TAZSource->incRef("buildTAZ");
870  TAZ->addChildElement(TAZSource);
871  // create TAZ Sink
872  GNETAZElement* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
873  TAZSink->incRef("buildTAZ");
874  TAZ->addChildElement(TAZSink);
875  }
876  }
877  // enable updating geometry again and update geometry of TAZ
878  net->enableUpdateGeometry();
879  // update TAZ Frame
880  TAZ->updateGeometry();
881  TAZ->updateParentAdditional();
882  return TAZ;
883 }
884 
885 
887 GNEAdditionalHandler::buildTAZSource(GNENet* net, bool allowUndoRedo, GNETAZElement* TAZ, GNEEdge* edge, double departWeight) {
888  GNETAZElement* TAZSink = nullptr;
889  // first check if a TAZSink in the same edge for the same TAZ
890  for (const auto& TAZElement : TAZ->getChildTAZElements()) {
891  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSINK) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
892  TAZSink = TAZElement;
893  }
894  }
895  // check if TAZSink has to be created
896  if (TAZSink == nullptr) {
897  // Create TAZ with weight 0 (default)
898  TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
899  if (allowUndoRedo) {
901  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSink, true), true);
902  net->getViewNet()->getUndoList()->p_end();
903  } else {
904  net->getAttributeCarriers()->insertTAZElement(TAZSink);
905  TAZSink->incRef("buildTAZSource");
906  }
907  }
908  // now check check if TAZSource exist
909  GNETAZElement* TAZSource = nullptr;
910  // first check if a TAZSink in the same edge for the same TAZ
911  for (const auto& TAZElement : TAZ->getChildTAZElements()) {
912  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
913  TAZSource = TAZElement;
914  }
915  }
916  // check if TAZSource has to be created
917  if (TAZSource == nullptr) {
918  // Create TAZ only with departWeight
919  TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, departWeight);
920  if (allowUndoRedo) {
922  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSource, true), true);
923  net->getViewNet()->getUndoList()->p_end();
924  } else {
925  net->getAttributeCarriers()->insertTAZElement(TAZSource);
926  TAZSource->incRef("buildTAZSource");
927  }
928  } else {
929  // update TAZ Attribute
930  if (allowUndoRedo) {
931  net->getViewNet()->getUndoList()->p_begin("update " + toString(SUMO_TAG_TAZSOURCE));
932  TAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), net->getViewNet()->getUndoList());
933  net->getViewNet()->getUndoList()->p_end();
934  } else {
935  TAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), nullptr);
936  TAZSource->incRef("buildTAZSource");
937  }
938  }
939  return TAZSource;
940 }
941 
942 
944 GNEAdditionalHandler::buildTAZSink(GNENet* net, bool allowUndoRedo, GNETAZElement* TAZ, GNEEdge* edge, double arrivalWeight) {
945  GNETAZElement* TAZSource = nullptr;
946  // first check if a TAZSink in the same edge for the same TAZ
947  for (const auto& TAZElement : TAZ->getChildTAZElements()) {
948  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
949  TAZSource = TAZElement;
950  }
951  }
952  // check if TAZSource has to be created
953  if (TAZSource == nullptr) {
954  // Create TAZ with empty value
955  TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
956  if (allowUndoRedo) {
958  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSource, true), true);
959  net->getViewNet()->getUndoList()->p_end();
960  } else {
961  net->getAttributeCarriers()->insertTAZElement(TAZSource);
962  TAZSource->incRef("buildTAZSink");
963  }
964  }
965  GNETAZElement* TAZSink = nullptr;
966  // first check if a TAZSink in the same edge for the same TAZ
967  for (const auto& TAZElement : TAZ->getChildTAZElements()) {
968  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSINK) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
969  TAZSink = TAZElement;
970  }
971  }
972  // check if TAZSink has to be created
973  if (TAZSink == nullptr) {
974  // Create TAZ only with arrivalWeight
975  TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, arrivalWeight);
976  if (allowUndoRedo) {
978  net->getViewNet()->getUndoList()->add(new GNEChange_TAZElement(TAZSink, true), true);
979  net->getViewNet()->getUndoList()->p_end();
980  } else {
981  net->getAttributeCarriers()->insertTAZElement(TAZSink);
982  TAZSink->incRef("buildTAZSink");
983  }
984  } else {
985  // update TAZ Attribute
986  if (allowUndoRedo) {
987  net->getViewNet()->getUndoList()->p_begin("update " + toString(SUMO_TAG_TAZSINK));
988  TAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), net->getViewNet()->getUndoList());
989  net->getViewNet()->getUndoList()->p_end();
990  } else {
991  TAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), nullptr);
992  TAZSink->incRef("buildTAZSink");
993  }
994  }
995  return TAZSink;
996 }
997 
998 
999 double
1000 GNEAdditionalHandler::getPosition(double pos, GNELane& lane, bool friendlyPos, const std::string& additionalID) {
1001  if (pos < 0) {
1002  pos = lane.getLaneShapeLength() + pos;
1003  }
1004  if (pos > lane.getLaneShapeLength()) {
1005  if (friendlyPos) {
1006  pos = lane.getLaneShapeLength() - (double) 0.1;
1007  } else {
1008  WRITE_WARNING("The position of additional '" + additionalID + "' lies beyond the lane's '" + lane.getID() + "' length.");
1009  }
1010  }
1011  return pos;
1012 }
1013 
1014 
1015 bool GNEAdditionalHandler::checkAndFixDetectorPosition(double& pos, const double laneLength, const bool friendlyPos) {
1016  if (fabs(pos) > laneLength) {
1017  if (!friendlyPos) {
1018  return false;
1019  } else if (pos < 0) {
1020  pos = 0;
1021  } else if (pos > laneLength) {
1022  pos = laneLength - 0.01;
1023  }
1024  }
1025  return true;
1026 }
1027 
1028 
1029 bool GNEAdditionalHandler::fixE2DetectorPosition(double& pos, double& length, const double laneLength, const bool friendlyPos) {
1030  if ((pos < 0) || ((pos + length) > laneLength)) {
1031  if (!friendlyPos) {
1032  return false;
1033  } else if (pos < 0) {
1034  pos = 0;
1035  } else if (pos > laneLength) {
1036  pos = laneLength - 0.01;
1037  length = 0;
1038  } else if ((pos + length) > laneLength) {
1039  length = laneLength - pos - 0.01;
1040  }
1041  }
1042  return true;
1043 }
1044 
1045 
1046 bool
1048  // check that busStopParent is a busStop
1049  assert(busStopParent->getTagProperty().getTag() == SUMO_TAG_BUS_STOP);
1050  // check if exist another acces for the same busStop in the given edge
1051  for (auto i : busStopParent->getChildAdditionals()) {
1052  for (auto j : edge->getLanes()) {
1053  if (i->getAttribute(SUMO_ATTR_LANE) == j->getID()) {
1054  return false;
1055  }
1056  }
1057  }
1058  return true;
1059 }
1060 
1061 
1062 bool
1064  // check that rerouter is correct
1065  assert(rerouter->getTagProperty().getTag() == SUMO_TAG_REROUTER);
1066  // declare a vector to keep sorted rerouter children
1067  std::vector<std::pair<SUMOTime, SUMOTime>> sortedIntervals;
1068  // iterate over child additional
1069  for (const auto& rerouterChild : rerouter->getChildAdditionals()) {
1070  if (!rerouterChild->getTagProperty().isSymbol()) {
1071  sortedIntervals.push_back(std::make_pair((SUMOTime)0., (SUMOTime)0.));
1072  // set begin and end
1073  sortedIntervals.back().first = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_BEGIN));
1074  sortedIntervals.back().second = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_END));
1075  }
1076  }
1077  // add new intervals
1078  sortedIntervals.push_back(std::make_pair(newBegin, newEnd));
1079  // sort children
1080  std::sort(sortedIntervals.begin(), sortedIntervals.end());
1081  // check overlapping after sorting
1082  for (int i = 0; i < (int)sortedIntervals.size() - 1; i++) {
1083  if (sortedIntervals.at(i).second > sortedIntervals.at(i + 1).first) {
1084  return false;
1085  }
1086  }
1087  return true;
1088 }
1089 
1090 
1091 
1092 
1093 bool
1094 GNEAdditionalHandler::parseAndBuildVaporizer(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1095  bool abort = false;
1096  // parse attributes of Vaporizer
1097  const std::string edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_VAPORIZER, SUMO_ATTR_ID, abort);
1098  SUMOTime begin = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_VAPORIZER, SUMO_ATTR_BEGIN, abort);
1099  SUMOTime end = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_VAPORIZER, SUMO_ATTR_END, abort);
1100  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_VAPORIZER, SUMO_ATTR_NAME, abort);
1101  // extra check for center element after creation
1102  bool centerAfterCreation = attrs.hasAttribute(GNE_ATTR_CENTER_AFTER_CREATION);
1103  // Continue if all parameters were successfully loaded
1104  if (!abort) {
1105  // get GNEEdge
1106  GNEEdge* edge = net->retrieveEdge(edgeID, false);
1107  // check that all parameters are valid
1108  if (edge == nullptr) {
1109  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_VAPORIZER) + " is not known.");
1110  } else if (net->retrieveAdditional(SUMO_TAG_VAPORIZER, edgeID, false) != nullptr) {
1111  WRITE_WARNING("There is already a " + toString(SUMO_TAG_VAPORIZER) + " in the edge '" + edgeID + "'.");
1112  } else if (begin > end) {
1113  WRITE_WARNING("Time interval of " + toString(SUMO_TAG_VAPORIZER) + " isn't valid. Attribute '" + toString(SUMO_ATTR_BEGIN) + "' is greater than attribute '" + toString(SUMO_ATTR_END) + "'.");
1114  } else {
1115  // build vaporizer
1116  GNEAdditional* additionalCreated = buildVaporizer(net, allowUndoRedo, edge, begin, end, name, centerAfterCreation);
1117  // check if insertion has to be commited
1118  if (insertedAdditionals) {
1119  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1120  }
1121  return true;
1122  }
1123  }
1124  return false;
1125 }
1126 
1127 
1128 bool
1129 GNEAdditionalHandler::parseAndBuildTAZ(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1130  bool abort = false;
1131  // parse attributes of Vaporizer
1132  const std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_TAZ, SUMO_ATTR_ID, abort);
1133  const PositionVector shape = GNEAttributeCarrier::parseAttributeFromXML<PositionVector>(attrs, id, SUMO_TAG_TAZ, SUMO_ATTR_SHAPE, abort);
1134  RGBColor color = GNEAttributeCarrier::parseAttributeFromXML<RGBColor>(attrs, id, SUMO_TAG_TAZ, SUMO_ATTR_COLOR, abort);
1135  // parse Netedit attributes
1136  bool blockMovement = false;
1138  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_TAZ, GNE_ATTR_BLOCK_MOVEMENT, abort);
1139  }
1140  // check edges
1141  std::vector<std::string> edgeIDs;
1142  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
1143  std::string parsedAttribute = attrs.get<std::string>(SUMO_ATTR_EDGES, id.c_str(), abort, false);
1144  edgeIDs = GNEAttributeCarrier::parse<std::vector<std::string> >(parsedAttribute);
1145  }
1146  // check if all edge IDs are valid
1147  std::vector<GNEEdge*> edges;
1148  for (auto i : edgeIDs) {
1149  GNEEdge* edge = net->retrieveEdge(i, false);
1150  if (edge == nullptr) {
1151  WRITE_WARNING("Invalid " + toString(SUMO_TAG_EDGE) + " with ID = '" + i + "' within taz '" + id + "'.");
1152  abort = true;
1153  } else {
1154  edges.push_back(edge);
1155  }
1156  }
1157  // Continue if all parameters were successfully loaded
1158  if (!abort) {
1159  // check that all parameters are valid
1160  if (net->retrieveTAZElement(SUMO_TAG_TAZ, id, false) != nullptr) {
1161  WRITE_WARNING("There is another " + toString(SUMO_TAG_TAZ) + " with the same ID='" + id + "'.");
1162  } else {
1163  // save ID of last created element
1164  GNETAZElement* TAZElementCreated = buildTAZ(net, allowUndoRedo, id, shape, color, edges, blockMovement);
1165  // check if insertion has to be commited
1166  if (insertedAdditionals) {
1167  insertedAdditionals->commitTAZElementInsertion(TAZElementCreated);
1168  }
1169  return true;
1170  }
1171  }
1172  return false;
1173 }
1174 
1175 
1176 bool
1177 GNEAdditionalHandler::parseAndBuildTAZSource(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1178  bool abort = false;
1179  // parse attributes of Vaporizer
1180  const std::string edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_TAZSOURCE, SUMO_ATTR_ID, abort);
1181  const double departWeight = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, edgeID, SUMO_TAG_TAZSOURCE, SUMO_ATTR_WEIGHT, abort);
1182  // Continue if all parameters were successfully loaded
1183  if (!abort) {
1184  // get edge and TAZ
1185  GNEEdge* edge = net->retrieveEdge(edgeID, false);
1186  GNETAZElement* TAZ = nullptr;
1187  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1188  if (insertedAdditionals) {
1189  TAZ = insertedAdditionals->getTAZElementParent(net, SUMO_TAG_TAZ);
1190  } else {
1191  bool ok = true;
1192  TAZ = net->retrieveTAZElement(SUMO_TAG_TAZ, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1193  }
1194  // check that all parameters are valid
1195  if (edge == nullptr) {
1196  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_TAZSOURCE) + " is not known.");
1197  } else if (TAZ == nullptr) {
1198  WRITE_WARNING("A " + toString(SUMO_TAG_TAZSOURCE) + " must be declared within the definition of a " + toString(SUMO_TAG_TAZ) + ".");
1199  } else {
1200  // save ID of last created element
1201  GNETAZElement* additionalCreated = buildTAZSource(net, allowUndoRedo, TAZ, edge, departWeight);
1202  // check if insertion has to be commited
1203  if (insertedAdditionals) {
1204  insertedAdditionals->commitTAZElementInsertion(additionalCreated);
1205  }
1206  return true;
1207  }
1208  }
1209  return false;
1210 }
1211 
1212 
1213 bool
1214 GNEAdditionalHandler::parseAndBuildTAZSink(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1215  bool abort = false;
1216  // parse attributes of Vaporizer
1217  const std::string edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_TAZSINK, SUMO_ATTR_ID, abort);
1218  const double arrivalWeight = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, edgeID, SUMO_TAG_TAZSINK, SUMO_ATTR_WEIGHT, abort);
1219  // Continue if all parameters were successfully loaded
1220  if (!abort) {
1221  // get edge and TAZ
1222  GNEEdge* edge = net->retrieveEdge(edgeID, false);
1223  GNETAZElement* TAZ = nullptr;
1224  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1225  if (insertedAdditionals) {
1226  TAZ = insertedAdditionals->getTAZElementParent(net, SUMO_TAG_TAZ);
1227  } else {
1228  bool ok = true;
1229  TAZ = net->retrieveTAZElement(SUMO_TAG_TAZ, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1230  }
1231  // check that all parameters are valid
1232  if (edge == nullptr) {
1233  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_TAZSINK) + " is not known.");
1234  } else if (TAZ == nullptr) {
1235  WRITE_WARNING("A " + toString(SUMO_TAG_TAZSINK) + " must be declared within the definition of a " + toString(SUMO_TAG_TAZ) + ".");
1236  } else {
1237  // save ID of last created element
1238  GNETAZElement* additionalCreated = buildTAZSink(net, allowUndoRedo, TAZ, edge, arrivalWeight);
1239  // check if insertion has to be commited
1240  if (insertedAdditionals) {
1241  insertedAdditionals->commitTAZElementInsertion(additionalCreated);
1242  }
1243  return true;
1244  }
1245  }
1246  return false;
1247 }
1248 
1249 
1250 bool
1251 GNEAdditionalHandler::parseAndBuildRouteProbe(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1252  bool abort = false;
1253  // parse attributes of RouteProbe
1254  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ROUTEPROBE, SUMO_ATTR_ID, abort);
1255  std::string edgeId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_ROUTEPROBE, SUMO_ATTR_EDGE, abort);
1256  std::string freq = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_ROUTEPROBE, SUMO_ATTR_FREQUENCY, abort);
1257  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_ROUTEPROBE, SUMO_ATTR_NAME, abort);
1258  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_ROUTEPROBE, SUMO_ATTR_FILE, abort);
1259  SUMOTime begin = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_ROUTEPROBE, SUMO_ATTR_BEGIN, abort);
1260  // extra check for center element after creation
1261  bool centerAfterCreation = attrs.hasAttribute(GNE_ATTR_CENTER_AFTER_CREATION);
1262  // Continue if all parameters were sucesfully loaded
1263  if (!abort) {
1264  // get edge
1265  GNEEdge* edge = net->retrieveEdge(edgeId, false);
1266  // check that all elements are valid
1267  if (net->retrieveAdditional(SUMO_TAG_ROUTEPROBE, id, false) != nullptr) {
1268  WRITE_WARNING("There is another " + toString(SUMO_TAG_ROUTEPROBE) + " with the same ID='" + id + "'.");
1269  } else if (edge == nullptr) {
1270  // Write error if lane isn't valid
1271  WRITE_WARNING("The edge '" + edgeId + "' to use within the " + toString(SUMO_TAG_ROUTEPROBE) + " '" + id + "' is not known.");
1272  } else {
1273  // Freq needs an extra check, because it can be empty
1274  if (GNEAttributeCarrier::canParse<double>(freq)) {
1275  if (GNEAttributeCarrier::parse<double>(freq) < 0) {
1276  WRITE_WARNING(toString(SUMO_ATTR_FREQUENCY) + "of " + toString(SUMO_TAG_ROUTEPROBE) + "'" + id + "' cannot be negative.");
1277  freq = "";
1278  }
1279  } else {
1280  if (freq.empty()) {
1281  WRITE_WARNING(toString(SUMO_ATTR_FREQUENCY) + "of " + toString(SUMO_TAG_ROUTEPROBE) + "'" + id + "' cannot be parsed to float.");
1282  }
1283  freq = "";
1284  }
1285  // save ID of last created element
1286  GNEAdditional* additionalCreated = buildRouteProbe(net, allowUndoRedo, id, edge, freq, name, file, begin, centerAfterCreation);
1287  // check if insertion has to be commited
1288  if (insertedAdditionals) {
1289  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1290  }
1291  return true;
1292  }
1293  }
1294  return false;
1295 }
1296 
1297 
1298 bool
1299 GNEAdditionalHandler::parseAndBuildCalibratorFlow(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1300  bool abort = false;
1301  // parse attributes of calibrator flows
1302  std::string vehicleTypeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_TYPE, abort);
1303  std::string routeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_ROUTE, abort);
1304  std::string vehsPerHour = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_VEHSPERHOUR, abort);
1305  std::string speed = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_SPEED, abort);
1306  RGBColor color = GNEAttributeCarrier::parseAttributeFromXML<RGBColor>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_COLOR, abort);
1307  std::string departLane = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_DEPARTLANE, abort);
1308  std::string departPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_DEPARTPOS, abort);
1309  std::string departSpeed = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_DEPARTSPEED, abort);
1310  std::string arrivalLane = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_ARRIVALLANE, abort);
1311  std::string arrivalPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_ARRIVALPOS, abort);
1312  std::string arrivalSpeed = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_ARRIVALSPEED, abort);
1313  std::string line = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_LINE, abort);
1314  int personNumber = GNEAttributeCarrier::parseAttributeFromXML<int>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_PERSON_NUMBER, abort);
1315  int containerNumber = GNEAttributeCarrier::parseAttributeFromXML<int>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_CONTAINER_NUMBER, abort);
1316  bool reroute = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_REROUTE, abort);
1317  std::string departPosLat = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_DEPARTPOS_LAT, abort);
1318  std::string arrivalPosLat = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_ARRIVALPOS_LAT, abort);
1319  SUMOTime begin = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_BEGIN, abort);
1320  SUMOTime end = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_FLOW_CALIBRATOR, SUMO_ATTR_END, abort);
1321  // Continue if all parameters were sucesfully loaded
1322  if (!abort) {
1323  // obtain route, vehicle type and calibrator parent
1324  GNEDemandElement* route = net->retrieveDemandElement(SUMO_TAG_ROUTE, routeID, false);
1325  GNEDemandElement* vtype = net->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleTypeID, false);
1326  GNEAdditional* calibrator = nullptr;
1327  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1328  if (insertedAdditionals) {
1329  calibrator = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_CALIBRATOR);
1330  } else {
1331  bool ok = true;
1332  calibrator = net->retrieveAdditional(SUMO_TAG_CALIBRATOR, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1333  }
1334  // check that all elements are valid
1335  if (route == nullptr) {
1336  WRITE_WARNING(toString(SUMO_TAG_FLOW_CALIBRATOR) + " cannot be created; their " + toString(SUMO_TAG_ROUTE) + " with ID = '" + routeID + "' doesn't exist");
1337  abort = true;
1338  } else if (vtype == nullptr) {
1339  WRITE_WARNING(toString(SUMO_TAG_FLOW_CALIBRATOR) + " cannot be created; their " + toString(SUMO_TAG_VTYPE) + " with ID = '" + vehicleTypeID + "' doesn't exist");
1340  abort = true;
1341  } else if ((vehsPerHour.empty()) && (speed.empty())) {
1342  WRITE_WARNING(toString(SUMO_TAG_FLOW_CALIBRATOR) + " cannot be created; At least parameters " + toString(SUMO_ATTR_VEHSPERHOUR) + " or " + toString(SUMO_ATTR_SPEED) + " has to be defined");
1343  abort = true;
1344  } else if (calibrator != nullptr) {
1345  // save ID of last created element
1346  GNEAdditional* additionalCreated = buildCalibratorFlow(net, allowUndoRedo, calibrator, route, vtype, vehsPerHour, speed, color, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
1347  line, personNumber, containerNumber, reroute, departPosLat, arrivalPosLat, begin, end);
1348  // check if insertion has to be commited
1349  if (insertedAdditionals) {
1350  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1351  }
1352  return true;
1353  }
1354  }
1355  return false;
1356 }
1357 
1358 
1359 bool
1360 GNEAdditionalHandler::parseAndBuildVariableSpeedSign(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1361  bool abort = false;
1362  // parse attributes of VSS
1363  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_VSS, SUMO_ATTR_ID, abort);
1364  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_VSS, SUMO_ATTR_NAME, abort);
1365  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_VSS, SUMO_ATTR_FILE, abort); // deprecated
1366  std::string lanesIDs = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_VSS, SUMO_ATTR_LANES, abort);
1367  Position pos = GNEAttributeCarrier::parseAttributeFromXML<Position>(attrs, id, SUMO_TAG_VSS, SUMO_ATTR_POSITION, abort);
1368  // parse Netedit attributes
1369  bool blockMovement = false;
1371  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_VSS, GNE_ATTR_BLOCK_MOVEMENT, abort);
1372  }
1373  // Continue if all parameters were sucesfully loaded
1374  if (!abort) {
1375  // obtain lanes
1376  std::vector<GNELane*> lanes;
1377  if (GNEAttributeCarrier::canParse<std::vector<GNELane*> >(net, lanesIDs, true)) {
1378  lanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(net, lanesIDs);
1379  }
1380  // check that all elements are valid
1381  if (net->retrieveAdditional(SUMO_TAG_VSS, id, false) != nullptr) {
1382  WRITE_WARNING("There is another " + toString(SUMO_TAG_VSS) + " with the same ID='" + id + "'.");
1383  } else if (lanes.size() == 0) {
1384  WRITE_WARNING("A Variable Speed Sign needs at least one lane.");
1385  } else {
1386  // save ID of last created element
1387  GNEAdditional* additionalCreated = buildVariableSpeedSign(net, allowUndoRedo, id, pos, lanes, name, blockMovement);
1388  // check if insertion has to be commited
1389  if (insertedAdditionals) {
1390  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1391  }
1392  return true;
1393  }
1394  }
1395  return false;
1396 }
1397 
1398 
1399 bool
1400 GNEAdditionalHandler::parseAndBuildVariableSpeedSignStep(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1401  bool abort = false;
1402  // Load step values
1403  double time = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_STEP, SUMO_ATTR_TIME, abort);
1404  double speed = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_STEP, SUMO_ATTR_SPEED, abort);
1405  // Continue if all parameters were sucesfully loaded
1406  if (!abort) {
1407  // get Variable Speed Signal
1408  GNEAdditional* variableSpeedSign = nullptr;
1409  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1410  if (insertedAdditionals) {
1411  variableSpeedSign = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_VSS);
1412  } else {
1413  bool ok = true;
1414  variableSpeedSign = net->retrieveAdditional(SUMO_TAG_VSS, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1415  }
1416  // check that all parameters are valid
1417  if (variableSpeedSign != nullptr) {
1418  // save ID of last created element
1419  GNEAdditional* additionalCreated = buildVariableSpeedSignStep(net, allowUndoRedo, variableSpeedSign, time, speed);
1420  // check if insertion has to be commited
1421  if (insertedAdditionals) {
1422  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1423  }
1424  return true;
1425  }
1426  }
1427  return false;
1428 }
1429 
1430 
1431 bool
1432 GNEAdditionalHandler::parseAndBuildRerouter(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1433  bool abort = false;
1434  // parse attributes of Rerouter
1435  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_REROUTER, SUMO_ATTR_ID, abort);
1436  std::string edgesIDs = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_EDGES, abort);
1437  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_NAME, abort);
1438  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_FILE, abort);
1439  double probability = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_PROB, abort);
1440  bool off = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_OFF, abort);
1441  SUMOTime timeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), abort, 0);
1442  const std::string vTypes = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id.c_str(), abort, "");
1443  Position pos = GNEAttributeCarrier::parseAttributeFromXML<Position>(attrs, id, SUMO_TAG_REROUTER, SUMO_ATTR_POSITION, abort);
1444  // parse Netedit attributes
1445  bool blockMovement = false;
1447  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_REROUTER, GNE_ATTR_BLOCK_MOVEMENT, abort);
1448  }
1449  // Continue if all parameters were sucesfully loaded
1450  if (!abort) {
1451  // obtain edges
1452  std::vector<GNEEdge*> edges;
1453  if (GNEAttributeCarrier::canParse<std::vector<GNEEdge*> >(net, edgesIDs, true)) {
1454  edges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(net, edgesIDs);
1455  }
1456  // check that all elements are valid
1457  if (net->retrieveAdditional(SUMO_TAG_REROUTER, id, false) != nullptr) {
1458  WRITE_WARNING("There is another " + toString(SUMO_TAG_REROUTER) + " with the same ID='" + id + "'.");
1459  } else if (edges.size() == 0) {
1460  WRITE_WARNING("A rerouter needs at least one Edge");
1461  } else {
1462  // save ID of last created element
1463  GNEAdditional* additionalCreated = buildRerouter(net, allowUndoRedo, id, pos, edges, probability, name,
1464  file, off, timeThreshold, vTypes, blockMovement);
1465  // check if insertion has to be commited
1466  if (insertedAdditionals) {
1467  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1468  }
1469  return true;
1470  }
1471  }
1472  return false;
1473 }
1474 
1475 
1476 bool
1477 GNEAdditionalHandler::parseAndBuildRerouterInterval(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1478  bool abort = false;
1479  // parse attributes of Rerouter
1480  SUMOTime begin = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_INTERVAL, SUMO_ATTR_BEGIN, abort);
1481  SUMOTime end = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, "", SUMO_TAG_INTERVAL, SUMO_ATTR_END, abort);
1482  // Continue if all parameters were sucesfully loaded
1483  if (!abort) {
1484  // obtain rerouter
1485  GNEAdditional* rerouter;
1486  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1487  if (insertedAdditionals) {
1488  rerouter = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_REROUTER);
1489  } else {
1490  bool ok = true;
1491  rerouter = net->retrieveAdditional(SUMO_TAG_REROUTER, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1492  }
1493  // special case for load multiple intervals in the same rerouter
1494  if (rerouter == nullptr) {
1495  GNEAdditional* lastInsertedRerouterInterval = nullptr;
1496  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1497  if (insertedAdditionals) {
1498  lastInsertedRerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1499  } else {
1500  bool ok = true;
1501  lastInsertedRerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1502  }
1503  if (lastInsertedRerouterInterval) {
1504  rerouter = lastInsertedRerouterInterval->getParentAdditionals().at(0);
1505  }
1506  }
1507  // check that rerouterInterval can be created
1508  if (begin >= end) {
1509  WRITE_WARNING(toString(SUMO_TAG_INTERVAL) + " cannot be created; Attribute " + toString(SUMO_ATTR_END) + " must be greather than " + toString(SUMO_ATTR_BEGIN) + ".");
1510  } else if (rerouter != nullptr) {
1511  // save ID of last created element
1512  GNEAdditional* additionalCreated = buildRerouterInterval(net, allowUndoRedo, rerouter, begin, end);
1513  // check if insertion has to be commited
1514  if (insertedAdditionals) {
1515  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1516  }
1517  return true;
1518  }
1519  }
1520  return false;
1521 }
1522 
1523 
1524 bool
1526  bool abort = false;
1527  // parse attributes of Rerouter
1528  std::string laneID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_LANE_REROUTE, SUMO_ATTR_ID, abort);
1529  std::string allow = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_LANE_REROUTE, SUMO_ATTR_ALLOW, abort);
1530  std::string disallow = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_LANE_REROUTE, SUMO_ATTR_DISALLOW, abort);
1531  // Continue if all parameters were sucesfully loaded
1532  if (!abort) {
1533  // obtain lane and rerouter interval
1534  GNELane* lane = net->retrieveLane(laneID, false, true);
1535  GNEAdditional* rerouterInterval = nullptr;
1536  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1537  if (insertedAdditionals) {
1538  rerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1539  } else {
1540  bool ok = true;
1541  rerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1542  }
1543  // check that all elements are valid
1544  if (lane == nullptr) {
1545  WRITE_WARNING("The lane '" + laneID + "' to use within the " + toString(SUMO_TAG_CLOSING_LANE_REROUTE) + " is not known.");
1546  } else if (rerouterInterval != nullptr) {
1547  // save ID of last created element
1548  GNEAdditional* additionalCreated = buildClosingLaneReroute(net, allowUndoRedo, rerouterInterval, lane, parseVehicleClasses(allow, disallow));
1549  // check if insertion has to be commited
1550  if (insertedAdditionals) {
1551  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1552  }
1553  return true;
1554  }
1555  }
1556  return false;
1557 }
1558 
1559 
1560 bool
1562  bool abort = false;
1563  // parse attributes of Rerouter
1564  std::string edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_REROUTE, SUMO_ATTR_ID, abort);
1565  std::string allow = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_REROUTE, SUMO_ATTR_ALLOW, abort);
1566  std::string disallow = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CLOSING_REROUTE, SUMO_ATTR_DISALLOW, abort);
1567  // Continue if all parameters were sucesfully loaded
1568  if (!abort) {
1569  // obtain edge and rerouter interval
1570  GNEEdge* edge = net->retrieveEdge(edgeID, false);
1571  GNEAdditional* rerouterInterval = nullptr;
1572  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1573  if (insertedAdditionals) {
1574  rerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1575  } else {
1576  bool ok = true;
1577  rerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1578  }
1579  // check that all elements are valid
1580  if (edge == nullptr) {
1581  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_CLOSING_REROUTE) + " is not known.");
1582  } else if (rerouterInterval != nullptr) {
1583  // save ID of last created element
1584  GNEAdditional* additionalCreated = buildClosingReroute(net, allowUndoRedo, rerouterInterval, edge, parseVehicleClasses(allow, disallow));
1585  // check if insertion has to be commited
1586  if (insertedAdditionals) {
1587  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1588  }
1589  return true;
1590  }
1591  }
1592  return false;
1593 }
1594 
1595 
1596 bool
1598  bool abort = false;
1599  // parse attributes of Rerouter
1600  std::string edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_DEST_PROB_REROUTE, SUMO_ATTR_ID, abort);
1601  double probability = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_DEST_PROB_REROUTE, SUMO_ATTR_PROB, abort);
1602  // Continue if all parameters were sucesfully loaded
1603  if (!abort) {
1604  // obtain edge and rerouter interval
1605  GNEEdge* edge = net->retrieveEdge(edgeID, false);
1606  GNEAdditional* rerouterInterval = nullptr;
1607  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1608  if (insertedAdditionals) {
1609  rerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1610  } else {
1611  bool ok = true;
1612  rerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1613  }
1614  // check that all elements are valid
1615  if (edge == nullptr) {
1616  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_DEST_PROB_REROUTE) + " is not known.");
1617  } else if (rerouterInterval != nullptr) {
1618  // save ID of last created element
1619  GNEAdditional* additionalCreated = builDestProbReroute(net, allowUndoRedo, rerouterInterval, edge, probability);
1620  // check if insertion has to be commited
1621  if (insertedAdditionals) {
1622  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1623  }
1624  return true;
1625  }
1626  }
1627  return false;
1628 }
1629 
1630 
1631 bool
1633  bool abort = false;
1634  // parse attributes of Rerouter
1635  std::string parkingAreaID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_PARKING_ZONE_REROUTE, SUMO_ATTR_ID, abort);
1636  double probability = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_PARKING_ZONE_REROUTE, SUMO_ATTR_PROB, abort);
1637  bool visible = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_PARKING_ZONE_REROUTE, SUMO_ATTR_VISIBLE, abort);
1638  // Continue if all parameters were sucesfully loaded
1639  if (!abort) {
1640  // obtain edge and rerouter interval
1641  GNEAdditional* parkingArea = net->retrieveAdditional(SUMO_TAG_PARKING_AREA, parkingAreaID, false);
1642  GNEAdditional* rerouterInterval = nullptr;
1643  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1644  if (insertedAdditionals) {
1645  rerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1646  } else {
1647  bool ok = true;
1648  rerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1649  }
1650  // check that all elements are valid
1651  if (parkingArea == nullptr) {
1652  WRITE_WARNING("The parkingArea '" + parkingAreaID + "' to use within the " + toString(SUMO_TAG_PARKING_ZONE_REROUTE) + " is not known.");
1653  } else if (rerouterInterval != nullptr) {
1654  // save ID of last created element
1655  GNEAdditional* additionalCreated = builParkingAreaReroute(net, allowUndoRedo, rerouterInterval, parkingArea, probability, visible);
1656  // check if insertion has to be commited
1657  if (insertedAdditionals) {
1658  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1659  }
1660  return true;
1661  }
1662  }
1663  return false;
1664 }
1665 
1666 
1667 bool
1669  bool abort = false;
1670  // parse attributes of Rerouter
1671  std::string routeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ROUTE_PROB_REROUTE, SUMO_ATTR_ID, abort);
1672  double probability = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_ROUTE_PROB_REROUTE, SUMO_ATTR_PROB, abort);
1673  // Continue if all parameters were sucesfully loaded
1674  if (!abort) {
1675  // obtain rerouter interval
1676  GNEAdditional* rerouterInterval = nullptr;
1677  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1678  if (insertedAdditionals) {
1679  rerouterInterval = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_INTERVAL);
1680  } else {
1681  bool ok = true;
1682  rerouterInterval = net->retrieveAdditional(SUMO_TAG_INTERVAL, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1683  }
1684  // check that all elements are valid
1685  if (rerouterInterval != nullptr) {
1686  // save ID of last created element
1687  GNEAdditional* additionalCreated = buildRouteProbReroute(net, allowUndoRedo, rerouterInterval, routeID, probability);
1688  // check if insertion has to be commited
1689  if (insertedAdditionals) {
1690  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1691  }
1692  return true;
1693  }
1694  }
1695  return false;
1696 }
1697 
1698 
1699 bool
1700 GNEAdditionalHandler::parseAndBuildBusStop(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1701  bool abort = false;
1702  // parse attributes of bus stop
1703  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_BUS_STOP, SUMO_ATTR_ID, abort);
1704  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_LANE, abort);
1705  std::string startPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_STARTPOS, abort);
1706  std::string endPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_ENDPOS, abort);
1707  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_NAME, abort);
1708  std::vector<std::string> lines = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_LINES, abort);
1709  const int personCapacity = GNEAttributeCarrier::parseAttributeFromXML<int>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_PERSON_CAPACITY, abort);
1710  const double parkingLength = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_PARKING_LENGTH, abort);
1711  bool friendlyPosition = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_BUS_STOP, SUMO_ATTR_FRIENDLY_POS, abort);
1712  // parse Netedit attributes
1713  bool blockMovement = false;
1715  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_BUS_STOP, GNE_ATTR_BLOCK_MOVEMENT, abort);
1716  }
1717  // Continue if all parameters were sucesfully loaded
1718  if (!abort) {
1719  // get pointer to lane
1720  GNELane* lane = net->retrieveLane(laneId, false, true);
1721  // check that all elements are valid
1722  if (net->retrieveAdditional(SUMO_TAG_BUS_STOP, id, false) != nullptr) {
1723  WRITE_WARNING("There is another " + toString(SUMO_TAG_BUS_STOP) + " with the same ID='" + id + "'.");
1724  } else if (lane == nullptr) {
1725  // Write error if lane isn't valid
1726  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_BUS_STOP) + " '" + id + "' is not known.");
1727  } else {
1728  // declare variables for start and end position
1729  double startPosDouble = 0;
1730  double endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1731  const double stoppingPlaceLength = (endPosDouble - startPosDouble);
1732  int parametersSet = 0;
1733  // check if startPos and endPos were defined
1734  if (GNEAttributeCarrier::canParse<double>(startPos)) {
1735  startPosDouble = GNEAttributeCarrier::parse<double>(startPos);
1736  parametersSet |= STOPPINGPLACE_STARTPOS_SET;
1737  }
1738  if (GNEAttributeCarrier::canParse<double>(endPos)) {
1739  endPosDouble = GNEAttributeCarrier::parse<double>(endPos);
1740  parametersSet |= STOPPINGPLACE_ENDPOS_SET;
1741  }
1742  // check if stoppingPlace has to be adjusted
1743  SUMORouteHandler::StopPos checkStopPosResult = SUMORouteHandler::checkStopPos(startPosDouble, endPosDouble, lane->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPosition);
1744  // update start and end positions depending of checkStopPosResult
1745  if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_STARTPOS) {
1746  startPosDouble = 0;
1747  endPosDouble = stoppingPlaceLength;
1748  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_ENDPOS) {
1749  startPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength() - stoppingPlaceLength;
1750  endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1751  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_LANELENGTH) {
1752  // Write error if position isn't valid
1753  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_BUS_STOP) + " with ID = '" + id + "'.");
1754  return false;
1755  }
1756  // save ID of last created element
1757  GNEAdditional* additionalCreated = buildBusStop(net, allowUndoRedo, id, lane, startPosDouble, endPosDouble, parametersSet,
1758  name, lines, personCapacity, parkingLength, friendlyPosition, blockMovement);
1759  // check if insertion has to be commited
1760  if (insertedAdditionals) {
1761  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1762  }
1763  return true;
1764  }
1765  }
1766  return false;
1767 }
1768 
1769 
1770 bool
1771 GNEAdditionalHandler::parseAndBuildContainerStop(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1772  bool abort = false;
1773  // parse attributes of container stop
1774  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_ID, abort);
1775  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_LANE, abort);
1776  std::string startPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_STARTPOS, abort);
1777  std::string endPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_ENDPOS, abort);
1778  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_NAME, abort);
1779  std::vector<std::string> lines = GNEAttributeCarrier::parseAttributeFromXML<std::vector<std::string> >(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_LINES, abort);
1780  bool friendlyPosition = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_CONTAINER_STOP, SUMO_ATTR_FRIENDLY_POS, abort);
1781  // parse Netedit attributes
1782  bool blockMovement = false;
1784  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_CONTAINER_STOP, GNE_ATTR_BLOCK_MOVEMENT, abort);
1785  }
1786  // Continue if all parameters were sucesfully loaded
1787  if (!abort) {
1788  // get pointer to lane
1789  GNELane* lane = net->retrieveLane(laneId, false, true);
1790  // check that all elements are valid
1791  if (net->retrieveAdditional(SUMO_TAG_CONTAINER_STOP, id, false) != nullptr) {
1792  WRITE_WARNING("There is another " + toString(SUMO_TAG_CONTAINER_STOP) + " with the same ID='" + id + "'.");
1793  } else if (lane == nullptr) {
1794  // Write error if lane isn't valid
1795  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_CONTAINER_STOP) + " '" + id + "' is not known.");
1796  } else {
1797  // declare variables for start and end position
1798  double startPosDouble = 0;
1799  double endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1800  const double stoppingPlaceLength = (endPosDouble - startPosDouble);
1801  int parametersSet = 0;
1802  // check if startPos and endPos were defined
1803  if (GNEAttributeCarrier::canParse<double>(startPos)) {
1804  startPosDouble = GNEAttributeCarrier::parse<double>(startPos);
1805  parametersSet |= STOPPINGPLACE_STARTPOS_SET;
1806  }
1807  if (GNEAttributeCarrier::canParse<double>(endPos)) {
1808  endPosDouble = GNEAttributeCarrier::parse<double>(endPos);
1809  parametersSet |= STOPPINGPLACE_ENDPOS_SET;
1810  }
1811  // check if stoppingPlace has to be adjusted
1812  SUMORouteHandler::StopPos checkStopPosResult = SUMORouteHandler::checkStopPos(startPosDouble, endPosDouble, lane->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPosition);
1813  // update start and end positions depending of checkStopPosResult
1814  if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_STARTPOS) {
1815  startPosDouble = 0;
1816  endPosDouble = stoppingPlaceLength;
1817  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_ENDPOS) {
1818  startPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength() - stoppingPlaceLength;
1819  endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1820  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_LANELENGTH) {
1821  // Write error if position isn't valid
1822  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_CONTAINER_STOP) + " with ID = '" + id + "'.");
1823  return false;
1824  }
1825  // save ID of last created element
1826  GNEAdditional* additionalCreated = buildContainerStop(net, allowUndoRedo, id, lane, startPosDouble, endPosDouble, parametersSet,
1827  name, lines, friendlyPosition, blockMovement);
1828  // check if insertion has to be commited
1829  if (insertedAdditionals) {
1830  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1831  }
1832  return true;
1833  }
1834  }
1835  return false;
1836 }
1837 
1838 
1839 bool
1840 GNEAdditionalHandler::parseAndBuildAccess(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1841  bool abort = false;
1842  // parse attributes of Entry
1843  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ACCESS, SUMO_ATTR_LANE, abort);
1844  std::string position = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ACCESS, SUMO_ATTR_POSITION, abort);
1845  std::string length = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_ACCESS, SUMO_ATTR_LENGTH, abort);
1846  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_ACCESS, SUMO_ATTR_FRIENDLY_POS, abort);
1847  // parse Netedit attributes
1848  bool blockMovement = false;
1850  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_ACCESS, GNE_ATTR_BLOCK_MOVEMENT, abort);
1851  }
1852  // Check if parsing of parameters was correct
1853  if (!abort) {
1854  double posDouble = GNEAttributeCarrier::parse<double>(position);
1855  // get lane and busStop parent
1856  GNELane* lane = net->retrieveLane(laneId, false, true);
1857  GNEAdditional* busStop = nullptr;
1858  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
1859  if (insertedAdditionals) {
1860  busStop = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_BUS_STOP);
1861  } else {
1862  bool ok = true;
1863  busStop = net->retrieveAdditional(SUMO_TAG_BUS_STOP, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
1864  }
1865  // check that all parameters are valid
1866  if (lane == nullptr) {
1867  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_ACCESS) + " is not known.");
1868  } else if (busStop == nullptr) {
1869  WRITE_WARNING("A " + toString(SUMO_TAG_ACCESS) + " must be declared within the definition of a " + toString(SUMO_TAG_BUS_STOP) + ".");
1870  } else if (!checkAndFixDetectorPosition(posDouble, lane->getLaneShapeLength(), friendlyPos)) {
1871  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_ACCESS) + ".");
1872  } else if (!accessCanBeCreated(busStop, lane->getParentEdge())) {
1873  WRITE_WARNING("Edge '" + lane->getParentEdge()->getID() + "' already has an Access for busStop '" + busStop->getID() + "'");
1874  } else {
1875  // save ID of last created element
1876  GNEAdditional* additionalCreated = buildAccess(net, allowUndoRedo, busStop, lane, posDouble, length, friendlyPos, blockMovement);
1877  // check if insertion has to be commited
1878  if (insertedAdditionals) {
1879  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1880  }
1881  return true;
1882  }
1883  }
1884  return false;
1885 }
1886 
1887 
1888 bool
1889 GNEAdditionalHandler::parseAndBuildChargingStation(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1890  bool abort = false;
1891  // parse attributes of charging station
1892  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CHARGING_STATION, SUMO_ATTR_ID, abort);
1893  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_LANE, abort);
1894  std::string startPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_STARTPOS, abort);
1895  std::string endPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_ENDPOS, abort);
1896  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_NAME, abort);
1897  double chargingPower = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_CHARGINGPOWER, abort);
1898  double efficiency = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_EFFICIENCY, abort);
1899  bool chargeInTransit = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_CHARGEINTRANSIT, abort);
1900  SUMOTime chargeDelay = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_CHARGEDELAY, abort);
1901  bool friendlyPosition = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_CHARGING_STATION, SUMO_ATTR_FRIENDLY_POS, abort);
1902  // parse Netedit attributes
1903  bool blockMovement = false;
1905  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_CHARGING_STATION, GNE_ATTR_BLOCK_MOVEMENT, abort);
1906  }
1907  // Continue if all parameters were sucesfully loaded
1908  if (!abort) {
1909  // get pointer to lane
1910  GNELane* lane = net->retrieveLane(laneId, false, true);
1911  // check that all elements are valid
1912  if (net->retrieveAdditional(SUMO_TAG_CHARGING_STATION, id, false) != nullptr) {
1913  WRITE_WARNING("There is another " + toString(SUMO_TAG_CHARGING_STATION) + " with the same ID='" + id + "'.");
1914  } else if (lane == nullptr) {
1915  // Write error if lane isn't valid
1916  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_CHARGING_STATION) + " '" + id + "' is not known.");
1917  } else {
1918  // declare variables for start and end position
1919  double startPosDouble = 0;
1920  double endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1921  const double stoppingPlaceLength = (endPosDouble - startPosDouble);
1922  int parametersSet = 0;
1923  // check if startPos and endPos were defined
1924  if (GNEAttributeCarrier::canParse<double>(startPos)) {
1925  startPosDouble = GNEAttributeCarrier::parse<double>(startPos);
1926  parametersSet |= STOPPINGPLACE_STARTPOS_SET;
1927  }
1928  if (GNEAttributeCarrier::canParse<double>(endPos)) {
1929  endPosDouble = GNEAttributeCarrier::parse<double>(endPos);
1930  parametersSet |= STOPPINGPLACE_ENDPOS_SET;
1931  }
1932  // check if stoppingPlace has to be adjusted
1933  SUMORouteHandler::StopPos checkStopPosResult = SUMORouteHandler::checkStopPos(startPosDouble, endPosDouble, lane->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPosition);
1934  // update start and end positions depending of checkStopPosResult
1935  if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_STARTPOS) {
1936  startPosDouble = 0;
1937  endPosDouble = stoppingPlaceLength;
1938  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_ENDPOS) {
1939  startPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength() - stoppingPlaceLength;
1940  endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1941  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_LANELENGTH) {
1942  // Write error if position isn't valid
1943  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_CHARGING_STATION) + " with ID = '" + id + "'.");
1944  return false;
1945  }
1946  // save ID of last created element
1947  GNEAdditional* additionalCreated = buildChargingStation(net, allowUndoRedo, id, lane, startPosDouble, endPosDouble, parametersSet,
1948  name, chargingPower, efficiency, chargeInTransit, chargeDelay, friendlyPosition, blockMovement);
1949  // check if insertion has to be commited
1950  if (insertedAdditionals) {
1951  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
1952  }
1953  return true;
1954  }
1955  }
1956  return false;
1957 }
1958 
1959 
1960 bool
1961 GNEAdditionalHandler::parseAndBuildParkingArea(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
1962  bool abort = false;
1963  // parse attributes of charging station
1964  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_PARKING_AREA, SUMO_ATTR_ID, abort);
1965  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_LANE, abort);
1966  std::string startPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_STARTPOS, abort);
1967  std::string endPos = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_ENDPOS, abort);
1968  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_NAME, abort);
1969  bool friendlyPosition = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_FRIENDLY_POS, abort);
1970  int roadSideCapacity = GNEAttributeCarrier::parseAttributeFromXML<int>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_ROADSIDE_CAPACITY, abort);
1971  bool onRoad = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_ONROAD, abort);
1972  double width = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_WIDTH, abort);
1973  std::string length = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_LENGTH, abort);
1974  double angle = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_PARKING_AREA, SUMO_ATTR_ANGLE, abort);
1975  // parse Netedit attributes
1976  bool blockMovement = false;
1978  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_PARKING_AREA, GNE_ATTR_BLOCK_MOVEMENT, abort);
1979  }
1980  // Continue if all parameters were sucesfully loaded
1981  if (!abort) {
1982  // get pointer to lane
1983  GNELane* lane = net->retrieveLane(laneId, false, true);
1984  // check that all elements are valid
1985  if (net->retrieveAdditional(SUMO_TAG_PARKING_AREA, id, false) != nullptr) {
1986  WRITE_WARNING("There is another " + toString(SUMO_TAG_PARKING_AREA) + " with the same ID='" + id + "'.");
1987  } else if (lane == nullptr) {
1988  // Write error if lane isn't valid
1989  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_PARKING_AREA) + " '" + id + "' is not known.");
1990  } else {
1991  // declare variables for start and end position
1992  double startPosDouble = 0;
1993  double endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
1994  const double stoppingPlaceLength = (endPosDouble - startPosDouble);
1995  int parametersSet = 0;
1996  // check if startPos and endPos were defined
1997  if (GNEAttributeCarrier::canParse<double>(startPos)) {
1998  startPosDouble = GNEAttributeCarrier::parse<double>(startPos);
1999  parametersSet |= STOPPINGPLACE_STARTPOS_SET;
2000  }
2001  if (GNEAttributeCarrier::canParse<double>(endPos)) {
2002  endPosDouble = GNEAttributeCarrier::parse<double>(endPos);
2003  parametersSet |= STOPPINGPLACE_ENDPOS_SET;
2004  }
2005  // check if stoppingPlace has to be adjusted
2006  SUMORouteHandler::StopPos checkStopPosResult = SUMORouteHandler::checkStopPos(startPosDouble, endPosDouble, lane->getParentEdge()->getNBEdge()->getFinalLength(), POSITION_EPS, friendlyPosition);
2007  // update start and end positions depending of checkStopPosResult
2008  if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_STARTPOS) {
2009  startPosDouble = 0;
2010  endPosDouble = stoppingPlaceLength;
2011  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_ENDPOS) {
2012  startPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength() - stoppingPlaceLength;
2013  endPosDouble = lane->getParentEdge()->getNBEdge()->getFinalLength();
2014  } else if (checkStopPosResult == SUMORouteHandler::StopPos::STOPPOS_INVALID_LANELENGTH) {
2015  // Write error if position isn't valid
2016  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_PARKING_AREA) + " with ID = '" + id + "'.");
2017  return false;
2018  }
2019  // save ID of last created element
2020  GNEAdditional* additionalCreated = buildParkingArea(net, allowUndoRedo, id, lane, startPosDouble, endPosDouble, parametersSet,
2021  name, friendlyPosition, roadSideCapacity, onRoad, width, length, angle, blockMovement);
2022  // check if insertion has to be commited
2023  if (insertedAdditionals) {
2024  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2025  }
2026  return true;
2027  }
2028  }
2029  return false;
2030 }
2031 
2032 
2033 bool
2034 GNEAdditionalHandler::parseAndBuildParkingSpace(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2035  bool abort = false;
2036  // parse attributes of Parking Spaces
2037  Position pos = GNEAttributeCarrier::parseAttributeFromXML<Position>(attrs, "", SUMO_TAG_PARKING_SPACE, SUMO_ATTR_POSITION, abort);
2038  double width = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_PARKING_SPACE, SUMO_ATTR_WIDTH, abort);
2039  double length = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_PARKING_SPACE, SUMO_ATTR_LENGTH, abort);
2040  double angle = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_PARKING_SPACE, SUMO_ATTR_ANGLE, abort);
2041  // parse Netedit attributes
2042  bool blockMovement = false;
2044  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_PARKING_SPACE, GNE_ATTR_BLOCK_MOVEMENT, abort);
2045  }
2046  // Continue if all parameters were sucesfully loaded
2047  if (!abort) {
2048  // get Parking Area Parent
2049  GNEAdditional* parkingAreaParent = nullptr;
2050  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
2051  if (insertedAdditionals) {
2052  parkingAreaParent = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_PARKING_AREA);
2053  } else {
2054  bool ok = true;
2055  parkingAreaParent = net->retrieveAdditional(SUMO_TAG_PARKING_AREA, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
2056  }
2057  // check that Parking Area Parent exists
2058  if (parkingAreaParent != nullptr) {
2059  // save ID of last created element
2060  GNEAdditional* additionalCreated = buildParkingSpace(net, allowUndoRedo, parkingAreaParent, pos, width, length, angle, blockMovement);
2061  // check if insertion has to be commited
2062  if (insertedAdditionals) {
2063  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2064  }
2065  return true;
2066  }
2067  }
2068  return false;
2069 }
2070 
2071 
2072 bool
2073 GNEAdditionalHandler::parseAndBuildCalibrator(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2074  bool abort = false;
2075  // due there is two differents calibrators, has to be parsed in a different way
2076  std::string edgeID, laneId, id;
2077  // change tag depending of XML parmeters
2078  if (attrs.hasAttribute(SUMO_ATTR_EDGE)) {
2079  id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_CALIBRATOR, SUMO_ATTR_ID, abort);
2080  edgeID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_EDGE, abort);
2081  std::string outfile = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_OUTPUT, abort);
2082  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_POSITION, abort);
2083  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_NAME, abort);
2084  SUMOTime freq = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_FREQUENCY, abort);
2085  std::string routeProbe = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_CALIBRATOR, SUMO_ATTR_ROUTEPROBE, abort);
2086  // extra check for center element after creation
2087  bool centerAfterCreation = attrs.hasAttribute(GNE_ATTR_CENTER_AFTER_CREATION);
2088  // Continue if all parameters were sucesfully loaded
2089  if (!abort) {
2090  // get pointer and edge
2091  GNEEdge* edge = net->retrieveEdge(edgeID, false);
2092  // check that all elements are valid
2093  if (net->retrieveAdditional(SUMO_TAG_CALIBRATOR, id, false) != nullptr) {
2094  WRITE_WARNING("There is another " + toString(SUMO_TAG_CALIBRATOR) + " with the same ID='" + id + "'.");
2095  } else if (edge == nullptr) {
2096  WRITE_WARNING("The edge '" + edgeID + "' to use within the " + toString(SUMO_TAG_CALIBRATOR) + " '" + id + "' is not known.");
2097  } else {
2098  // save ID of last created element
2099  GNEAdditional* additionalCreated = buildCalibrator(net, allowUndoRedo, id, edge, position, name, outfile, freq, routeProbe, centerAfterCreation);
2100  // check if insertion has to be commited
2101  if (insertedAdditionals) {
2102  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2103  }
2104  return true;
2105  }
2106  }
2107  } else if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
2108  id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_ID, abort);
2109  laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_LANE, abort);
2110  std::string outfile = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_OUTPUT, abort);
2111  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_POSITION, abort);
2112  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_NAME, abort);
2113  SUMOTime freq = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_FREQUENCY, abort);
2114  std::string routeProbe = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_LANECALIBRATOR, SUMO_ATTR_ROUTEPROBE, abort);
2115  // extra check for center element after creation
2116  bool centerAfterCreation = attrs.hasAttribute(GNE_ATTR_CENTER_AFTER_CREATION);
2117  // Continue if all parameters were sucesfully loaded
2118  if (!abort) {
2119  // get pointer to lane
2120  GNELane* lane = net->retrieveLane(laneId, false, true);
2121  // check that all elements are valid
2122  if (net->retrieveAdditional(SUMO_TAG_LANECALIBRATOR, id, false) != nullptr) {
2123  WRITE_WARNING("There is another " + toString(SUMO_TAG_CALIBRATOR) + " with the same ID='" + id + "'.");
2124  } else if (lane == nullptr) {
2125  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_CALIBRATOR) + " '" + id + "' is not known.");
2126  } else {
2127  // save ID of last created element
2128  GNEAdditional* additionalCreated = buildCalibrator(net, allowUndoRedo, id, lane, position, name, outfile, freq, routeProbe, centerAfterCreation);
2129  // check if insertion has to be commited
2130  if (insertedAdditionals) {
2131  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2132  }
2133  return true;
2134  }
2135  }
2136  } else {
2137  WRITE_WARNING("additional " + toString(SUMO_TAG_CALIBRATOR) + " must have either a lane or an edge attribute.");
2138  }
2139  return false;
2140 }
2141 
2142 
2143 bool
2144 GNEAdditionalHandler::parseAndBuildDetectorE1(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2145  bool abort = false;
2146  // parse attributes of E1
2147  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_E1DETECTOR, SUMO_ATTR_ID, abort);
2148  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_LANE, abort);
2149  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_POSITION, abort);
2150  SUMOTime frequency = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_FREQUENCY, abort);
2151  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_FILE, abort);
2152  std::string vehicleTypes = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_VTYPES, abort);
2153  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_NAME, abort);
2154  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_E1DETECTOR, SUMO_ATTR_FRIENDLY_POS, abort);
2155  // parse Netedit attributes
2156  bool blockMovement = false;
2158  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_E1DETECTOR, GNE_ATTR_BLOCK_MOVEMENT, abort);
2159  }
2160  // Continue if all parameters were sucesfully loaded
2161  if (!abort) {
2162  // get pointer to lane
2163  GNELane* lane = net->retrieveLane(laneId, false, true);
2164  // check that all elements are valid
2165  if (net->retrieveAdditional(SUMO_TAG_E1DETECTOR, id, false) != nullptr) {
2166  WRITE_WARNING("There is another " + toString(SUMO_TAG_E1DETECTOR) + " with the same ID='" + id + "'.");
2167  } else if (lane == nullptr) {
2168  // Write error if lane isn't valid
2169  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_E1DETECTOR) + " '" + id + "' is not known.");
2170  } else if (!checkAndFixDetectorPosition(position, lane->getLaneShapeLength(), friendlyPos)) {
2171  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_E1DETECTOR) + " with ID = '" + id + "'.");
2172  } else {
2173  // save ID of last created element
2174  GNEAdditional* additionalCreated = buildDetectorE1(net, allowUndoRedo, id, lane, position, frequency, file, vehicleTypes, name, friendlyPos, blockMovement);
2175  // check if insertion has to be commited
2176  if (insertedAdditionals) {
2177  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2178  }
2179  return true;
2180  }
2181  }
2182  return false;
2183 }
2184 
2185 
2186 bool
2187 GNEAdditionalHandler::parseAndBuildDetectorE2(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2188  // Tag E2 detectors can build either E2 single lanes or E2 multilanes, depending of attribute "lanes"
2190  bool abort = false;
2191  // start parsing ID
2192  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", E2Tag, SUMO_ATTR_ID, abort);
2193  // parse attributes of E2 SingleLanes
2194  std::string laneId = (E2Tag == SUMO_TAG_E2DETECTOR) ? GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_LANE, abort) : "";
2195  double length = (E2Tag == SUMO_TAG_E2DETECTOR) ? GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, E2Tag, SUMO_ATTR_LENGTH, abort) : 0;
2196  // parse attributes of E2 Multilanes
2197  std::string laneIds = (E2Tag == SUMO_TAG_E2DETECTOR_MULTILANE) ? GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_LANES, abort) : "";
2198  double endPos = (E2Tag == SUMO_TAG_E2DETECTOR_MULTILANE) ? GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, E2Tag, SUMO_ATTR_ENDPOS, abort) : 0;
2199  // parse common attributes
2200  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, E2Tag, SUMO_ATTR_POSITION, abort);
2201  std::string frequency = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_FREQUENCY, abort);
2202  const std::string trafficLight = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_TLID, abort);
2203  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_FILE, abort);
2204  std::string vehicleTypes = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_VTYPES, abort);
2205  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_NAME, abort);
2206  SUMOTime haltingTimeThreshold = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, E2Tag, SUMO_ATTR_HALTING_TIME_THRESHOLD, abort);
2207  double haltingSpeedThreshold = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, E2Tag, SUMO_ATTR_HALTING_SPEED_THRESHOLD, abort);
2208  double jamDistThreshold = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, E2Tag, SUMO_ATTR_JAM_DIST_THRESHOLD, abort);
2209  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, E2Tag, SUMO_ATTR_FRIENDLY_POS, abort);
2210  // parse Netedit attributes
2211  bool blockMovement = false;
2213  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, E2Tag, GNE_ATTR_BLOCK_MOVEMENT, abort);
2214  }
2215  // cont attribute is deprecated
2216  GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, E2Tag, SUMO_ATTR_CONT, abort);
2217  // Continue if all parameters were sucesfully loaded
2218  if (!abort) {
2219  // check if at leas lane or laneIDS are defined
2220  if (laneId.empty() && laneIds.empty()) {
2221  WRITE_WARNING("A " + toString(E2Tag) + " needs at least a lane or a list of lanes.");
2222  } else if (!frequency.empty() && !trafficLight.empty()) {
2223  WRITE_WARNING("Frecuency and TL cannot be defined at the same time.");
2224  } else {
2225  // update frequency (temporal)
2226  if (frequency.empty() && trafficLight.empty()) {
2227  frequency = "900.00";
2228  }
2229  // get pointer to lane
2230  GNELane* lane = net->retrieveLane(laneId, false, true);
2231  // get list of lanes
2232  std::vector<GNELane*> lanes;
2233  bool laneConsecutives = true;
2234  if (GNEAttributeCarrier::canParse<std::vector<GNELane*> >(net, laneIds, false)) {
2235  lanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(net, laneIds);
2236  // check if lanes are consecutives
2237  laneConsecutives = GNEAttributeCarrier::lanesConsecutives(lanes);
2238  }
2239  // check that all elements are valid
2240  if (net->retrieveAdditional(E2Tag, id, false) != nullptr) {
2241  // write error if neither lane nor lane aren't defined
2242  WRITE_WARNING("There is another " + toString(E2Tag) + " with the same ID='" + id + "'.");
2243  } else if (attrs.hasAttribute(SUMO_ATTR_LANE) && (lane == nullptr)) {
2244  // Write error if lane isn't valid
2245  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(E2Tag) + " '" + id + "' is not known.");
2246  } else if (attrs.hasAttribute(SUMO_ATTR_LANES) && lanes.empty()) {
2247  // Write error if lane isn't valid
2248  WRITE_WARNING("The list of lanes cannot be empty.");
2249  } else if (attrs.hasAttribute(SUMO_ATTR_LANES) && lanes.empty()) {
2250  // Write error if lane isn't valid
2251  WRITE_WARNING("The list of lanes '" + laneIds + "' to use within the " + toString(E2Tag) + " '" + id + "' isn't valid.");
2252  } else if (!lanes.empty() && !laneConsecutives) {
2253  WRITE_WARNING("The lanes '" + laneIds + "' to use within the " + toString(E2Tag) + " '" + id + "' aren't consecutives.");
2254  } else if (lane && !fixE2DetectorPosition(position, length, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
2255  WRITE_WARNING("Invalid position for " + toString(E2Tag) + " with ID = '" + id + "'.");
2256  } else if (!lanes.empty() && !fixE2DetectorPosition(position, length, lanes.front()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
2257  WRITE_WARNING("Invalid position for " + toString(E2Tag) + " with ID = '" + id + "'.");
2258  } else if (!lanes.empty() && !fixE2DetectorPosition(endPos, length, lanes.back()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
2259  WRITE_WARNING("Invalid end position for " + toString(E2Tag) + " with ID = '" + id + "'.");
2260  } else if (lane) {
2261  // save ID of last created element
2262  GNEAdditional* additionalCreated = buildSingleLaneDetectorE2(net, allowUndoRedo, id, lane, position, length, frequency, trafficLight, file, vehicleTypes,
2263  name, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, friendlyPos, blockMovement);
2264  // check if insertion has to be commited
2265  if (insertedAdditionals) {
2266  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2267  }
2268  return true;
2269  } else {
2270  // save ID of last created element
2271  GNEAdditional* additionalCreated = buildMultiLaneDetectorE2(net, allowUndoRedo, id, lanes, position, endPos, frequency, trafficLight, file, vehicleTypes,
2272  name, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, friendlyPos, blockMovement);
2273  // check if insertion has to be commited
2274  if (insertedAdditionals) {
2275  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2276  }
2277  return true;
2278  }
2279  }
2280  }
2281  return false;
2282 }
2283 
2284 
2285 bool
2286 GNEAdditionalHandler::parseAndBuildDetectorE3(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2287  bool abort = false;
2288  // parse attributes of E3
2289  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_E3DETECTOR, SUMO_ATTR_ID, abort);
2290  SUMOTime frequency = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_FREQUENCY, abort);
2291  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_FILE, abort);
2292  std::string vehicleTypes = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_VTYPES, abort);
2293  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_NAME, abort);
2294  SUMOTime haltingTimeThreshold = GNEAttributeCarrier::parseAttributeFromXML<SUMOTime>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_HALTING_TIME_THRESHOLD, abort);
2295  double haltingSpeedThreshold = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_HALTING_SPEED_THRESHOLD, abort);
2296  Position pos = GNEAttributeCarrier::parseAttributeFromXML<Position>(attrs, id, SUMO_TAG_E3DETECTOR, SUMO_ATTR_POSITION, abort);
2297  // parse Netedit attributes
2298  bool blockMovement = false;
2300  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_E3DETECTOR, GNE_ATTR_BLOCK_MOVEMENT, abort);
2301  }
2302  // Continue if all parameters were sucesfully loaded
2303  if (!abort) {
2304  // check that all elements are valid
2305  if (net->retrieveAdditional(SUMO_TAG_E3DETECTOR, id, false) != nullptr) {
2306  WRITE_WARNING("There is another " + toString(SUMO_TAG_E3DETECTOR) + " with the same ID='" + id + "'.");
2307  } else {
2308  // save ID of last created element
2309  GNEAdditional* additionalCreated = buildDetectorE3(net, allowUndoRedo, id, pos, frequency, file, vehicleTypes, name, haltingTimeThreshold, haltingSpeedThreshold, blockMovement);
2310  // check if insertion has to be commited
2311  if (insertedAdditionals) {
2312  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2313  }
2314  return true;
2315  }
2316  }
2317  return false;
2318 }
2319 
2320 
2321 bool
2322 GNEAdditionalHandler::parseAndBuildDetectorEntry(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2323  bool abort = false;
2324  // parse attributes of Entry
2325  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_DET_ENTRY, SUMO_ATTR_LANE, abort);
2326  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_DET_ENTRY, SUMO_ATTR_POSITION, abort);
2327  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_DET_ENTRY, SUMO_ATTR_FRIENDLY_POS, abort);
2328  // parse Netedit attributes
2329  bool blockMovement = false;
2331  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_DET_ENTRY, GNE_ATTR_BLOCK_MOVEMENT, abort);
2332  }
2333  // Check if parsing of parameters was correct
2334  if (!abort) {
2335  // get lane and E3 parent
2336  GNELane* lane = net->retrieveLane(laneId, false, true);
2337  GNEAdditional* E3Parent = nullptr;
2338  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
2339  if (insertedAdditionals) {
2340  E3Parent = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_E3DETECTOR);
2341  } else {
2342  bool ok = true;
2343  E3Parent = net->retrieveAdditional(SUMO_TAG_E3DETECTOR, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
2344  }
2345  // check that all parameters are valid
2346  if (lane == nullptr) {
2347  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_DET_ENTRY) + " is not known.");
2348  } else if (!checkAndFixDetectorPosition(position, lane->getLaneShapeLength(), friendlyPos)) {
2349  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_DET_ENTRY) + ".");
2350  } else if (E3Parent) {
2351  // save ID of last created element
2352  GNEAdditional* additionalCreated = buildDetectorEntry(net, allowUndoRedo, E3Parent, lane, position, friendlyPos, blockMovement);
2353  // check if insertion has to be commited
2354  if (insertedAdditionals) {
2355  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2356  }
2357  return true;
2358  }
2359  }
2360  return false;
2361 }
2362 
2363 
2364 bool
2365 GNEAdditionalHandler::parseAndBuildDetectorExit(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2366  bool abort = false;
2367  // parse attributes of Exit
2368  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_DET_EXIT, SUMO_ATTR_LANE, abort);
2369  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, "", SUMO_TAG_DET_EXIT, SUMO_ATTR_POSITION, abort);
2370  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_DET_EXIT, SUMO_ATTR_FRIENDLY_POS, abort);
2371  // parse Netedit attributes
2372  bool blockMovement = false;
2374  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_DET_EXIT, GNE_ATTR_BLOCK_MOVEMENT, abort);
2375  }
2376  // Check if parsing of parameters was correct
2377  if (!abort) {
2378  // get lane and E3 parent
2379  GNELane* lane = net->retrieveLane(laneId, false, true);
2380  GNEAdditional* E3Parent = nullptr;
2381  // obtain parent depending if we're loading or creating it using GNEAdditionalFrame
2382  if (insertedAdditionals) {
2383  E3Parent = insertedAdditionals->getAdditionalParent(net, SUMO_TAG_E3DETECTOR);
2384  } else {
2385  bool ok = true;
2386  E3Parent = net->retrieveAdditional(SUMO_TAG_E3DETECTOR, attrs.get<std::string>(GNE_ATTR_PARENT, "", ok));
2387  }
2388  // check that all parameters are valid
2389  if (lane == nullptr) {
2390  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_DET_EXIT) + " is not known.");
2391  } else if (!checkAndFixDetectorPosition(position, lane->getLaneShapeLength(), friendlyPos)) {
2392  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_DET_EXIT) + ".");
2393  } else if (E3Parent) {
2394  // save ID of last created element
2395  GNEAdditional* additionalCreated = buildDetectorExit(net, allowUndoRedo, E3Parent, lane, position, friendlyPos, blockMovement);
2396  // check if insertion has to be commited
2397  if (insertedAdditionals) {
2398  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2399  }
2400  return true;
2401  }
2402  }
2403  return false;
2404 }
2405 
2406 
2407 bool
2408 GNEAdditionalHandler::parseAndBuildDetectorE1Instant(GNENet* net, bool allowUndoRedo, const SUMOSAXAttributes& attrs, LastInsertedElement* insertedAdditionals) {
2409  bool abort = false;
2410  // parse attributes of E1Instant
2411  std::string id = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_ID, abort);
2412  std::string laneId = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_LANE, abort);
2413  double position = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_POSITION, abort);
2414  std::string file = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_FILE, abort);
2415  std::string vehicleTypes = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_VTYPES, abort);
2416  std::string name = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_NAME, abort);
2417  bool friendlyPos = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, SUMO_ATTR_FRIENDLY_POS, abort);
2418  // parse Netedit attributes
2419  bool blockMovement = false;
2421  blockMovement = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, id, SUMO_TAG_INSTANT_INDUCTION_LOOP, GNE_ATTR_BLOCK_MOVEMENT, abort);
2422  }
2423  // Continue if all parameters were sucesfully loaded
2424  if (!abort) {
2425  // get pointer to lane
2426  GNELane* lane = net->retrieveLane(laneId, false, true);
2427  // check that all elements are valid
2428  if (net->retrieveAdditional(SUMO_TAG_INSTANT_INDUCTION_LOOP, id, false) != nullptr) {
2429  WRITE_WARNING("There is another " + toString(SUMO_TAG_INSTANT_INDUCTION_LOOP) + " with the same ID='" + id + "'.");
2430  } else if (lane == nullptr) {
2431  // Write error if lane isn't valid
2432  WRITE_WARNING("The lane '" + laneId + "' to use within the " + toString(SUMO_TAG_INSTANT_INDUCTION_LOOP) + " '" + id + "' is not known.");
2433  } else if (!checkAndFixDetectorPosition(position, lane->getLaneShapeLength(), friendlyPos)) {
2434  WRITE_WARNING("Invalid position for " + toString(SUMO_TAG_INSTANT_INDUCTION_LOOP) + " with ID = '" + id + "'.");
2435  } else {
2436  // save ID of last created element
2437  GNEAdditional* additionalCreated = buildDetectorE1Instant(net, allowUndoRedo, id, lane, position, file, vehicleTypes, name, friendlyPos, blockMovement);
2438  // check if insertion has to be commited
2439  if (insertedAdditionals) {
2440  insertedAdditionals->commitAdditionalInsertion(additionalCreated);
2441  }
2442  return true;
2443  }
2444  }
2445  return false;
2446 }
2447 
2448 // ===========================================================================
2449 // private method definitions
2450 // ===========================================================================
2451 
2452 void
2454  bool abort = false;
2455  // parse attributes of polygons
2456  std::string polygonID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_POLY, SUMO_ATTR_ID, abort);
2457  PositionVector shape = GNEAttributeCarrier::parseAttributeFromXML<PositionVector>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_SHAPE, abort);
2458  double layer = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_LAYER, abort);
2459  bool fill = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, "", SUMO_TAG_POLY, SUMO_ATTR_FILL, abort);
2460  double lineWidth = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_LINEWIDTH, abort);
2461  std::string type = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_TYPE, abort);
2462  RGBColor color = GNEAttributeCarrier::parseAttributeFromXML<RGBColor>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_COLOR, abort);
2463  double angle = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_ANGLE, abort);
2464  std::string imgFile = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_IMGFILE, abort);
2465  bool relativePath = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, polygonID, SUMO_TAG_POLY, SUMO_ATTR_RELATIVEPATH, abort);
2466  // check if ID is valid
2467  if (SUMOXMLDefinitions::isValidTypeID(polygonID) == false) {
2468  WRITE_WARNING("Invalid characters for polygon ID");
2469  abort = true;
2470  }
2471  // Continue if all parameters were sucesfully loaded
2472  if (!abort) {
2473  // check if shape must be loaded as geo attribute
2474  bool geo = false;
2476  if (attrs.getOpt<bool>(SUMO_ATTR_GEO, polygonID.c_str(), abort, false)) {
2477  geo = true;
2478  bool success = true;
2479  for (int i = 0; i < (int)shape.size(); i++) {
2480  success &= gch->x2cartesian_const(shape[i]);
2481  }
2482  if (!success) {
2483  WRITE_WARNING("Unable to project coordinates for polygon '" + polygonID + "'.");
2484  return;
2485  }
2486  }
2487  // check if img file is absolute
2488  if (imgFile != "" && !FileHelpers::isAbsolute(imgFile)) {
2489  imgFile = FileHelpers::getConfigurationRelative(getFileName(), imgFile);
2490  }
2491  // create polygon, or show an error if polygon already exists
2492  if (!myNet->getAttributeCarriers()->addPolygon(polygonID, type, color, layer, angle, imgFile, relativePath, shape, geo, fill, lineWidth, false)) {
2493  WRITE_WARNING("Polygon with ID '" + polygonID + "' already exists.");
2494  } else {
2495  // commit shape element insertion
2497  }
2498  }
2499 }
2500 
2501 
2502 void
2504  bool abort = false;
2505  // parse attributes of POIs
2506  std::string POIID = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, "", SUMO_TAG_POI, SUMO_ATTR_ID, abort);
2507  // POIs can be defined using a X,Y position,...
2508  Position pos = attrs.hasAttribute(SUMO_ATTR_X) ? GNEAttributeCarrier::parseAttributeFromXML<Position>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_POSITION, abort) : Position::INVALID;
2509  // ... a Lon-Lat,...
2510  double lon = attrs.hasAttribute(SUMO_ATTR_LON) ? GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_LON, abort) : GNEAttributeCarrier::INVALID_POSITION;
2511  double lat = attrs.hasAttribute(SUMO_ATTR_LAT) ? GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_LAT, abort) : GNEAttributeCarrier::INVALID_POSITION;
2512  // .. or as Lane-PosLane
2513  std::string laneID = attrs.hasAttribute(SUMO_ATTR_LANE) ? GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, POIID, SUMO_TAG_POILANE, SUMO_ATTR_LANE, abort) : "";
2514  double lanePos = attrs.hasAttribute(SUMO_ATTR_POSITION) ? GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POILANE, SUMO_ATTR_POSITION, abort) : GNEAttributeCarrier::INVALID_POSITION;
2515  double lanePosLat = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POILANE, SUMO_ATTR_POSITION_LAT, abort);
2516  // continue with common parameters
2517  double layer = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_LAYER, abort);
2518  std::string type = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_TYPE, abort);
2519  RGBColor color = GNEAttributeCarrier::parseAttributeFromXML<RGBColor>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_COLOR, abort);
2520  double angle = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_ANGLE, abort);
2521  std::string imgFile = GNEAttributeCarrier::parseAttributeFromXML<std::string>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_IMGFILE, abort);
2522  bool relativePath = GNEAttributeCarrier::parseAttributeFromXML<bool>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_RELATIVEPATH, abort);
2523  double width = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_WIDTH, abort);
2524  double height = GNEAttributeCarrier::parseAttributeFromXML<double>(attrs, POIID, SUMO_TAG_POI, SUMO_ATTR_HEIGHT, abort);
2525  // check if ID is valid
2526  if (SUMOXMLDefinitions::isValidTypeID(POIID) == false) {
2527  WRITE_WARNING("Invalid characters for POI ID");
2528  abort = true;
2529  }
2530  // Continue if all parameters were sucesfully loaded
2531  if (!abort) {
2532  // check if img file is absolute
2533  if (imgFile != "" && !FileHelpers::isAbsolute(imgFile)) {
2534  imgFile = FileHelpers::getConfigurationRelative(getFileName(), imgFile);
2535  }
2536  // check if lane exist
2537  if (laneID != "" && !myNet->retrieveLane(laneID, false)) {
2538  WRITE_WARNING("The lane '" + laneID + "' to use within the PoI '" + POIID + "' is not known.");
2539  return;
2540  }
2541  // check position
2542  bool useGeo = false;
2543  // if position is invalid, then is either a POILane or a GEOPoi
2544  if (pos == Position::INVALID) {
2545  // try computing x,y from lane,pos
2546  if (laneID != "") {
2547  // if LaneID is defined, then is a POILane
2548  pos = getLanePos(POIID, laneID, lanePos, lanePosLat);
2549  } else {
2550  // try computing x,y from lon,lat
2552  WRITE_WARNING("Either (x, y), (lon, lat) or (lane, pos) must be specified for PoI '" + POIID + "'.");
2553  return;
2554  } else if (!GeoConvHelper::getFinal().usingGeoProjection()) {
2555  WRITE_WARNING("(lon, lat) is specified for PoI '" + POIID + "' but no geo-conversion is specified for the network.");
2556  return;
2557  }
2558  // set GEO Position
2559  pos.set(lon, lat);
2560  useGeo = true;
2561  if (!GeoConvHelper::getFinal().x2cartesian_const(pos)) {
2562  WRITE_WARNING("Unable to project coordinates for PoI '" + POIID + "'.");
2563  return;
2564  }
2565  }
2566  }
2567  // create POI, or show an error if POI already exists
2568  if (!myNet->getAttributeCarriers()->addPOI(POIID, type, color, pos, useGeo, laneID, lanePos, lanePosLat, layer, angle, imgFile, relativePath, width, height, false)) {
2569  WRITE_WARNING("POI with ID '" + POIID + "' already exists.");
2570  } else {
2571  // commit shape element insertion
2573  }
2574  }
2575 }
2576 
2577 
2578 void
2580  // we have two cases: if we're parsing a Shape or we're parsing an Additional
2581  if (getLastParameterised()) {
2582  bool ok = true;
2583  std::string key;
2584  if (attrs.hasAttribute(SUMO_ATTR_KEY)) {
2585  // obtain key
2586  key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
2587  if (key.empty()) {
2588  WRITE_WARNING("Error parsing key from shape parameter. Key cannot be empty");
2589  ok = false;
2590  }
2592  WRITE_WARNING("Error parsing key from shape parameter. Key contains invalid characters");
2593  ok = false;
2594  }
2595  } else {
2596  WRITE_WARNING("Error parsing key from shape parameter. Key doesn't exist");
2597  ok = false;
2598  }
2599  // circumventing empty string test
2600  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
2601  // set parameter in last inserted additional
2602  if (ok) {
2603  WRITE_DEBUG("Inserting parameter '" + key + "|" + val + "' into shape.");
2604  getLastParameterised()->setParameter(key, val);
2605  }
2607  // first check if given additional supports parameters
2609  bool ok = true;
2610  std::string key;
2611  if (attrs.hasAttribute(SUMO_ATTR_KEY)) {
2612  // obtain key
2613  key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
2614  if (key.empty()) {
2615  WRITE_WARNING("Error parsing key from additional parameter. Key cannot be empty");
2616  ok = false;
2617  }
2619  WRITE_WARNING("Error parsing key from additional parameter. Key contains invalid characters");
2620  ok = false;
2621  }
2622  } else {
2623  WRITE_WARNING("Error parsing key from additional parameter. Key doesn't exist");
2624  ok = false;
2625  }
2626  // circumventing empty string test
2627  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
2628  // check double values
2629  if (myLastInsertedElement->getLastInsertedAdditional()->getTagProperty().hasDoubleParameters() && !GNEAttributeCarrier::canParse<double>(val)) {
2630  WRITE_WARNING("Error parsing value from additional float parameter. Value cannot be parsed to float");
2631  ok = false;
2632  }
2633  // set parameter in last inserted additional
2634  if (ok) {
2635  WRITE_DEBUG("Inserting parameter '" + key + "|" + val + "' into additional " + myLastInsertedElement->getLastInsertedAdditional()->getTagStr() + ".");
2637  }
2638  } else {
2639  WRITE_WARNING("Additionals of type '" + myLastInsertedElement->getLastInsertedAdditional()->getTagStr() + "' doesn't support parameters");
2640  }
2642  // first check if given shape supports parameters
2644  bool ok = true;
2645  std::string key;
2646  if (attrs.hasAttribute(SUMO_ATTR_KEY)) {
2647  // obtain key
2648  key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
2649  if (key.empty()) {
2650  WRITE_WARNING("Error parsing key from shape parameter. Key cannot be empty");
2651  ok = false;
2652  }
2654  WRITE_WARNING("Error parsing key from shape parameter. Key contains invalid characters");
2655  ok = false;
2656  }
2657  } else {
2658  WRITE_WARNING("Error parsing key from shape parameter. Key doesn't exist");
2659  ok = false;
2660  }
2661  // circumventing empty string test
2662  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
2663  // check double values
2664  if (myLastInsertedElement->getLastInsertedShape()->getTagProperty().hasDoubleParameters() && !GNEAttributeCarrier::canParse<double>(val)) {
2665  WRITE_WARNING("Error parsing value from shape float parameter. Value cannot be parsed to float");
2666  ok = false;
2667  }
2668  // set parameter in last inserted shape
2669  if (ok) {
2670  WRITE_DEBUG("Inserting parameter '" + key + "|" + val + "' into shape " + myLastInsertedElement->getLastInsertedShape()->getTagStr() + ".");
2672  }
2673  } else {
2674  WRITE_WARNING("Shape of type '" + myLastInsertedElement->getLastInsertedShape()->getTagStr() + "' doesn't support parameters");
2675  }
2677  // first check if given TAZ supports parameters
2679  bool ok = true;
2680  std::string key;
2681  if (attrs.hasAttribute(SUMO_ATTR_KEY)) {
2682  // obtain key
2683  key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
2684  if (key.empty()) {
2685  WRITE_WARNING("Error parsing key from TAZ parameter. Key cannot be empty");
2686  ok = false;
2687  }
2689  WRITE_WARNING("Error parsing key from TAZ parameter. Key contains invalid characters");
2690  ok = false;
2691  }
2692  } else {
2693  WRITE_WARNING("Error parsing key from TAZ parameter. Key doesn't exist");
2694  ok = false;
2695  }
2696  // circumventing empty string test
2697  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
2698  // check double values
2699  if (myLastInsertedElement->getLastInsertedTAZElement()->getTagProperty().hasDoubleParameters() && !GNEAttributeCarrier::canParse<double>(val)) {
2700  WRITE_WARNING("Error parsing value from TAZ float parameter. Value cannot be parsed to float");
2701  ok = false;
2702  }
2703  // set parameter in last inserted TAZ
2704  if (ok) {
2705  WRITE_DEBUG("Inserting parameter '" + key + "|" + val + "' into TAZ " + myLastInsertedElement->getLastInsertedTAZElement()->getTagStr() + ".");
2707  }
2708  } else {
2709  WRITE_WARNING("TAZ of type '" + myLastInsertedElement->getLastInsertedTAZElement()->getTagStr() + "' doesn't support parameters");
2710  }
2711  } else {
2712  WRITE_WARNING("Parameters has to be declared within the definition of an additional, shape or TAZ element");
2713  }
2714 }
2715 
2716 // ===========================================================================
2717 // GNEAdditionalHandler::LastInsertedElement method definitions
2718 // ===========================================================================
2719 
2720 void
2722  myInsertedElements.push_back(StackElement(tag));
2723 }
2724 
2725 
2726 void
2728  myInsertedElements.back().additional = additional;
2729 }
2730 
2731 
2732 void
2734  myInsertedElements.back().shape = shapeCreated;
2735 }
2736 
2737 
2738 void
2740  myInsertedElements.back().TAZElement = TAZElementCreated;
2741 }
2742 
2743 
2744 void
2746  if (!myInsertedElements.empty()) {
2747  myInsertedElements.pop_back();
2748  }
2749 }
2750 
2751 
2754  if (myInsertedElements.size() < 2) {
2755  // currently we're finding parent additional in the additional XML root
2756  WRITE_WARNING("A " + toString(myInsertedElements.back().tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2757  return nullptr;
2758  } else {
2759  if (myInsertedElements.size() < 2) {
2760  // additional was hierarchically bad loaded, then return nullptr
2761  return nullptr;
2762  } else if ((myInsertedElements.end() - 2)->additional == nullptr) {
2763  WRITE_WARNING(toString(expectedTag) + " parent of " + toString((myInsertedElements.end() - 1)->tag) + " was not loaded sucesfully.");
2764  // parent additional wasn't sucesfully loaded, then return nullptr
2765  return nullptr;
2766  }
2767  GNEAdditional* retrievedAdditional = nullptr;
2768  // special case for rerouters
2769  if ((myInsertedElements.size() == 3) && (myInsertedElements.at(0).tag == SUMO_TAG_REROUTER) && (myInsertedElements.at(1).tag == SUMO_TAG_INTERVAL)) {
2770  retrievedAdditional = myInsertedElements.at(1).additional;
2771  } else {
2772  retrievedAdditional = net->retrieveAdditional((myInsertedElements.end() - 2)->tag, (myInsertedElements.end() - 2)->additional->getID(), false);
2773  }
2774  if (retrievedAdditional == nullptr) {
2775  // additional doesn't exist
2776  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2777  return nullptr;
2778  } else if (retrievedAdditional->getTagProperty().getTag() != expectedTag) {
2779  // invalid parent additional
2780  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " cannot be declared within the definition of a " + retrievedAdditional->getTagStr() + ".");
2781  return nullptr;
2782  } else {
2783  return retrievedAdditional;
2784  }
2785  }
2786 }
2787 
2788 
2789 GNEShape*
2791  if (myInsertedElements.size() < 2) {
2792  // currently we're finding parent shape in the shape XML root
2793  WRITE_WARNING("A " + toString(myInsertedElements.back().tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2794  return nullptr;
2795  } else {
2796  if (myInsertedElements.size() < 2) {
2797  // shape was hierarchically bad loaded, then return nullptr
2798  return nullptr;
2799  } else if ((myInsertedElements.end() - 2)->shape == nullptr) {
2800  WRITE_WARNING(toString(expectedTag) + " parent of " + toString((myInsertedElements.end() - 1)->tag) + " was not loaded sucesfully.");
2801  // parent shape wasn't sucesfully loaded, then return nullptr
2802  return nullptr;
2803  }
2804  GNEShape* retrievedShape = net->retrieveShape((myInsertedElements.end() - 2)->tag, (myInsertedElements.end() - 2)->shape->getID(), false);
2805  if (retrievedShape == nullptr) {
2806  // shape doesn't exist
2807  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2808  return nullptr;
2809  } else if (retrievedShape->getTagProperty().getTag() != expectedTag) {
2810  // invalid parent shape
2811  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " cannot be declared within the definition of a " + retrievedShape->getTagStr() + ".");
2812  return nullptr;
2813  } else {
2814  return retrievedShape;
2815  }
2816  }
2817 }
2818 
2819 
2822  if (myInsertedElements.size() < 2) {
2823  // currently we're finding parent TAZElement in the TAZElement XML root
2824  WRITE_WARNING("A " + toString(myInsertedElements.back().tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2825  return nullptr;
2826  } else {
2827  if (myInsertedElements.size() < 2) {
2828  // TAZElement was hierarchically bad loaded, then return nullptr
2829  return nullptr;
2830  } else if ((myInsertedElements.end() - 2)->TAZElement == nullptr) {
2831  WRITE_WARNING(toString(expectedTag) + " parent of " + toString((myInsertedElements.end() - 1)->tag) + " was not loaded sucesfully.");
2832  // parent TAZElement wasn't sucesfully loaded, then return nullptr
2833  return nullptr;
2834  }
2835  GNETAZElement* retrievedTAZElement = net->retrieveTAZElement((myInsertedElements.end() - 2)->tag, (myInsertedElements.end() - 2)->TAZElement->getID(), false);
2836  if (retrievedTAZElement == nullptr) {
2837  // TAZElement doesn't exist
2838  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " must be declared within the definition of a " + toString(expectedTag) + ".");
2839  return nullptr;
2840  } else if (retrievedTAZElement->getTagProperty().getTag() != expectedTag) {
2841  // invalid parent TAZElement
2842  WRITE_WARNING("A " + toString((myInsertedElements.end() - 1)->tag) + " cannot be declared within the definition of a " + retrievedTAZElement->getTagStr() + ".");
2843  return nullptr;
2844  } else {
2845  return retrievedTAZElement;
2846  }
2847  }
2848 }
2849 
2850 
2853  // ierate in reverse mode over myInsertedElements to obtain last inserted additional
2854  for (std::vector<StackElement>::const_reverse_iterator i = myInsertedElements.rbegin(); i != myInsertedElements.rend(); i++) {
2855  // we need to avoid Tag Param because isn't an additional
2856  if (i->tag != SUMO_TAG_PARAM) {
2857  return i->additional;
2858  }
2859  }
2860  return nullptr;
2861 }
2862 
2863 
2864 GNEShape*
2866  // ierate in reverse mode over myInsertedElements to obtain last inserted shape
2867  for (std::vector<StackElement>::const_reverse_iterator i = myInsertedElements.rbegin(); i != myInsertedElements.rend(); i++) {
2868  // we need to avoid Tag Param because isn't a shape
2869  if (i->tag != SUMO_TAG_PARAM) {
2870  return i->shape;
2871  }
2872  }
2873  return nullptr;
2874 }
2875 
2876 
2879  // ierate in reverse mode over myInsertedElements to obtain last inserted TAZElement
2880  for (std::vector<StackElement>::const_reverse_iterator i = myInsertedElements.rbegin(); i != myInsertedElements.rend(); i++) {
2881  // we need to avoid Tag Param because isn't a TAZElement
2882  if (i->tag != SUMO_TAG_PARAM) {
2883  return i->TAZElement;
2884  }
2885  }
2886  return nullptr;
2887 }
2888 
2889 
2891  tag(_tag),
2892  additional(nullptr),
2893  shape(nullptr),
2894  TAZElement(nullptr) {
2895 }
2896 
2897 /****************************************************************************/
const int STOPPINGPLACE_STARTPOS_SET
const int STOPPINGPLACE_ENDPOS_SET
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:286
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:278
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_CLOSING_REROUTE
reroute of type closing
@ SUMO_TAG_REROUTER
A rerouter.
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_E2DETECTOR
an e2 detector
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle type
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_E2DETECTOR_MULTILANE
an e2 detector over multiple lanes (used by Netedit)
@ SUMO_TAG_NOTHING
invalid tag
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_LANECALIBRATOR
A calibrator placed over lane (used in netedit)
@ SUMO_TAG_STEP
trigger: a step description
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_PARKING_ZONE_REROUTE
entry for an alternative parking zone
@ SUMO_TAG_ROUTE_PROB_REROUTE
probability of route of a reroute
@ SUMO_TAG_DET_ENTRY
an e3 entry point
@ SUMO_TAG_PARKING_SPACE
A parking space for a single vehicle within a parking area.
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_INSTANT_INDUCTION_LOOP
An instantenous induction loop.
@ SUMO_TAG_POILANE
begin/end of the description of a Point of interest over Lane (used by Netedit)
@ SUMO_TAG_DEST_PROB_REROUTE
probability of destiny of a reroute
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ SUMO_TAG_E1DETECTOR
an e1 detector
@ SUMO_TAG_DET_EXIT
an e3 exit point
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_LANE_AREA_DETECTOR
alternative tag for e2 detector
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ SUMO_TAG_CLOSING_LANE_REROUTE
lane of a reroute of type closing
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_ENTRY_EXIT_DETECTOR
alternative tag for e3 detector
@ SUMO_TAG_E3DETECTOR
an e3 detector
@ SUMO_TAG_VSS
A variable speed sign.
@ SUMO_TAG_FLOW_CALIBRATOR
a flow definition within in Calibrator (used in NETEDIT)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_LINES
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_LANE
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_CONT
@ SUMO_ATTR_LON
@ GNE_ATTR_CENTER_AFTER_CREATION
flag to center camera after element creation
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_FILE
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_DEPARTPOS_LAT
@ SUMO_ATTR_PARKING_LENGTH
@ GNE_ATTR_BLOCK_MOVEMENT
block movement of a graphic element
@ SUMO_ATTR_ENDPOS
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_X
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_OFF
@ SUMO_ATTR_ROUTEPROBE
@ SUMO_ATTR_LINEWIDTH
@ SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_CONTAINER_NUMBER
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_GEO
@ SUMO_ATTR_LINE
@ SUMO_ATTR_LANES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_WEIGHT
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_CHARGEINTRANSIT
Allow/disallow charge in transit in Charging Stations.
@ SUMO_ATTR_FILL
Fill the polygon.
@ SUMO_ATTR_NAME
@ SUMO_ATTR_LAYER
A layer number.
@ SUMO_ATTR_HALTING_SPEED_THRESHOLD
@ SUMO_ATTR_FREQUENCY
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_HEIGHT
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ROADSIDE_CAPACITY
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_TLID
link,node: the traffic light id responsible for this link
@ SUMO_ATTR_OUTPUT
@ SUMO_ATTR_CHARGINGPOWER
@ SUMO_ATTR_PROB
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_ONROAD
@ SUMO_ATTR_LAT
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_PERSON_NUMBER
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_EFFICIENCY
Eficiency of the charge in Charging Stations.
@ SUMO_ATTR_ID
@ SUMO_ATTR_VISIBLE
@ SUMO_ATTR_ARRIVALPOS_LAT
@ SUMO_ATTR_IMGFILE
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_KEY
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_CHARGEDELAY
Delay in the charge of charging stations.
@ SUMO_ATTR_TIME
trigger: the time of the step
@ SUMO_ATTR_RELATIVEPATH
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:129
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:117
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:135
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:123
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
static std::string getFilePath(const std::string &path)
Removes the file information from the given path.
Definition: FileHelpers.cpp:75
Stack used to save the last inserted element.
std::vector< StackElement > myInsertedElements
vector used as stack
GNEShape * getLastInsertedShape() const
return last inserted shape
GNETAZElement * getTAZElementParent(GNENet *net, SumoXMLTag expectedTag) const
retrieve parent TAZElement correspond to current status of myInsertedElements
void commitTAZElementInsertion(GNETAZElement *TAZElementCreated)
commit TAZElement element insertion (used to save last correct created element)
GNETAZElement * getLastInsertedTAZElement() const
return last inserted TAZElement
GNEAdditional * getLastInsertedAdditional() const
return last inserted additional
void commitAdditionalInsertion(GNEAdditional *additionalCreated)
commit additional element insertion (used to save last correct created element)
void commitShapeInsertion(GNEShape *shapeCreated)
commit shape element insertion (used to save last correct created element)
void popElement()
pop last inserted element (used only in function myEndElement)
GNEShape * getShapeParent(GNENet *net, SumoXMLTag expectedTag) const
retrieve parent shape correspond to current status of myInsertedElements
void insertElement(SumoXMLTag tag)
insert new element (called only in function myStartElement)
GNEAdditional * getAdditionalParent(GNENet *net, SumoXMLTag expectedTag) const
retrieve parent additional correspond to current status of myInsertedElements
Builds additional objects for GNENet (busStops, chargingStations, detectors, etc.....
static bool checkOverlappingRerouterIntervals(GNEAdditional *rerouter, SUMOTime newBegin, SUMOTime newEnd)
check if an overlapping is produced in rerouter if a interval with certain begin and end is inserted
static bool checkAndFixDetectorPosition(double &pos, const double laneLength, const bool friendlyPos)
check if the position of a detector over a lane is valid
static bool parseAndBuildTAZSource(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Builds a TAZ Source.
static bool parseAndBuildRerouterClosingLaneReroute(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Closing Lane reroute.
static bool parseAndBuildTAZSink(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Builds a TAZ Sink.
static GNEAdditional * buildMultiLaneDetectorE2(GNENet *net, bool allowUndoRedo, const std::string &id, const std::vector< GNELane * > &lanes, double pos, double endPos, const std::string &freq, const std::string &trafficLight, const std::string &filename, const std::string &vehicleTypes, const std::string &name, SUMOTime timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos, bool blockMovement)
Builds a multi-lane Area Detector (E2)
static GNEAdditional * buildChargingStation(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, const double startPos, const double endPos, const int parametersSet, const std::string &name, double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay, bool friendlyPosition, bool blockMovement)
Builds a charging Station.
void parseAndBuildPoly(const SUMOSAXAttributes &attrs)
Parses his values and builds a Poly.
static GNEAdditional * buildVaporizer(GNENet *net, bool allowUndoRedo, GNEEdge *edge, SUMOTime start, SUMOTime endTime, const std::string &name, bool centerAfterCreation)
Builds a vaporizer (lane speed additional)
static bool parseAndBuildBusStop(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a bus stop.
static bool parseAndBuildDetectorExit(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Exit detector.
static GNEAdditional * buildBusStop(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, const double startPos, const double endPos, const int parametersSet, const std::string &name, const std::vector< std::string > &lines, int personCapacity, double parkingLength, bool friendlyPosition, bool blockMovement)
Builds a bus stop.
static GNEAdditional * buildClosingLaneReroute(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterIntervalParent, GNELane *closedLane, SVCPermissions permissions)
static bool parseAndBuildParkingSpace(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a parking space.
static GNEAdditional * buildVariableSpeedSign(GNENet *net, bool allowUndoRedo, const std::string &id, Position pos, const std::vector< GNELane * > &destLanes, const std::string &name, bool blockMovement)
Builds a VariableSpeedSign (lane speed additional)
static bool buildAdditional(GNENet *net, bool allowUndoRedo, SumoXMLTag tag, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Build additionals.
static bool parseAndBuildRerouter(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a rerouter.
static GNEAdditional * builParkingAreaReroute(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterIntervalParent, GNEAdditional *newParkignArea, double probability, bool visible)
static bool accessCanBeCreated(GNEAdditional *busStopParent, GNEEdge *edge)
check if a GNEAccess can be created in a certain Edge
static bool parseAndBuildCalibratorFlow(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses flow values of Calibrators.
static bool parseAndBuildRerouterClosingReroute(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Closing Reroute.
static GNEAdditional * buildDetectorE1(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, double pos, SUMOTime freq, const std::string &filename, const std::string &vehicleTypes, const std::string &name, bool friendlyPos, bool blockMovement)
Builds a induction loop detector (E1)
static bool parseAndBuildChargingStation(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a charging station.
static GNEAdditional * builDestProbReroute(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterIntervalParent, GNEEdge *newEdgeDestination, double probability)
static GNEAdditional * buildClosingReroute(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterIntervalParent, GNEEdge *closedEdge, SVCPermissions permissions)
static GNETAZElement * buildTAZSink(GNENet *net, bool allowUndoRedo, GNETAZElement *TAZ, GNEEdge *edge, double arrivalWeight)
Builds a TAZSink (Traffic Assignment Zone)
static GNEAdditional * buildDetectorE3(GNENet *net, bool allowUndoRedo, const std::string &id, Position pos, SUMOTime freq, const std::string &filename, const std::string &vehicleTypes, const std::string &name, SUMOTime timeThreshold, double speedThreshold, bool blockMovement)
Builds a multi entry exit detector (E3)
static bool parseAndBuildVaporizer(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Builds a Vaporizer.
static bool fixE2DetectorPosition(double &pos, double &length, const double laneLength, const bool friendlyPos)
check if the position of a detector over a lane is valid
double getPosition(double pos, GNELane &lane, bool friendlyPos, const std::string &additionalID)
extracts the position, checks whether it shall be mirrored and checks whether it is within the lane.
static bool parseAndBuildRerouterParkingAreaReroute(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a parkingAreaReroute.
static bool parseAndBuildCalibrator(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a mesoscopic or microscopic calibrator.
static bool parseAndBuildTAZ(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Builds a TAZ.
LastInsertedElement * myLastInsertedElement
LastInsertedElement used for insert children.
static GNETAZElement * buildTAZSource(GNENet *net, bool allowUndoRedo, GNETAZElement *TAZ, GNEEdge *edge, double departWeight)
Builds a TAZSource (Traffic Assignment Zone)
static bool parseAndBuildRouteProbe(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds routeProbe.
static bool parseAndBuildDetectorE1(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a induction loop detector (GNENet *net, bool allowUndoRedo,...
static GNEAdditional * buildSingleLaneDetectorE2(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, double pos, double length, const std::string &freq, const std::string &trafficLight, const std::string &filename, const std::string &vehicleTypes, const std::string &name, SUMOTime timeThreshold, double speedThreshold, double jamThreshold, bool friendlyPos, bool blockMovement)
Builds a single-lane Area Detector (E2)
static GNEAdditional * buildParkingArea(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, const double startPos, const double endPos, const int parametersSet, const std::string &name, bool friendlyPosition, int roadSideCapacity, bool onRoad, double width, const std::string &length, double angle, bool blockMovement)
Builds a Parking Area.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static bool parseAndBuildRerouterInterval(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Rerouter Interval.
static GNEAdditional * buildRouteProbe(GNENet *net, bool allowUndoRedo, const std::string &id, GNEEdge *edge, const std::string &freq, const std::string &name, const std::string &file, SUMOTime begin, bool centerAfterCreation)
builds a Route probe
static GNEAdditional * buildDetectorEntry(GNENet *net, bool allowUndoRedo, GNEAdditional *E3Parent, GNELane *lane, double pos, bool friendlyPos, bool blockMovement)
Builds a entry detector (E3)
GNEAdditionalHandler(const std::string &file, GNENet *net, GNEAdditional *additionalParent=nullptr)
Constructor.
static bool parseAndBuildDetectorE1Instant(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Instant induction loop detector (GNENet *net, bool allowUndoRedo,...
static bool parseAndBuildParkingArea(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a parking area.
static GNEAdditional * buildVariableSpeedSignStep(GNENet *net, bool allowUndoRedo, GNEAdditional *VSSParent, double time, double speed)
Builds a VariableSpeedSign Step.
static GNEAdditional * buildCalibrator(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, double pos, const std::string &name, const std::string &outfile, SUMOTime freq, const std::string &routeprobe, bool centerAfterCreation)
builds a microscopic calibrator over a lane
void myEndElement(int element)
Called when a closing tag occurs.
static GNETAZElement * buildTAZ(GNENet *net, bool allowUndoRedo, const std::string &id, const PositionVector &shape, const RGBColor &color, const std::vector< GNEEdge * > &edges, bool blockMovement)
Builds a TAZ (Traffic Assignment Zone)
static bool parseAndBuildDetectorE3(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a multi entry exit detector (GNENet *net, bool allowUndoRedo,...
static GNEAdditional * buildRerouter(GNENet *net, bool allowUndoRedo, const std::string &id, Position pos, const std::vector< GNEEdge * > &edges, double prob, const std::string &name, const std::string &file, bool off, SUMOTime timeThreshold, const std::string &vTypes, bool blockMovement)
builds a rerouter
static bool parseAndBuildVariableSpeedSign(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Variable Speed Signal (GNENet *net, bool allowUndoRedo,...
static GNEAdditional * buildDetectorExit(GNENet *net, bool allowUndoRedo, GNEAdditional *E3Parent, GNELane *lane, double pos, bool friendlyPos, bool blockMovement)
Builds a exit detector (E3)
GNENet * myNet
pointer to net
static bool parseAndBuildDetectorE2(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a lane area detector (GNENet *net, bool allowUndoRedo,...
void parseAndBuildPOI(const SUMOSAXAttributes &attrs)
Parses his values and builds a POI.
static GNEAdditional * buildParkingSpace(GNENet *net, bool allowUndoRedo, GNEAdditional *parkingAreaParent, Position pos, double width, double length, double angle, bool blockMovement)
Builds a Parking Space.
static bool parseAndBuildContainerStop(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a container stop.
static GNEAdditional * buildRouteProbReroute(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterIntervalParent, const std::string &newRouteId, double probability)
static GNEAdditional * buildContainerStop(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, const double startPos, const double endPos, const int parametersSet, const std::string &name, const std::vector< std::string > &lines, bool friendlyPosition, bool blockMovement)
Builds a container stop.
void parseParameter(const SUMOSAXAttributes &attrs)
Parse parameter and insert it in the last created additional.
static GNEAdditional * buildRerouterInterval(GNENet *net, bool allowUndoRedo, GNEAdditional *rerouterParent, SUMOTime begin, SUMOTime end)
builds a rerouter interval
static GNEAdditional * buildDetectorE1Instant(GNENet *net, bool allowUndoRedo, const std::string &id, GNELane *lane, double pos, const std::string &filename, const std::string &vehicleTypes, const std::string &name, bool friendlyPos, bool blockMovement)
Builds a Instant Induction Loop Detector (E1Instant)
static GNEAdditional * buildAccess(GNENet *net, bool allowUndoRedo, GNEAdditional *busStop, GNELane *lane, double pos, const std::string &length, bool friendlyPos, bool blockMovement)
Builds an Access.
static bool parseAndBuildVariableSpeedSignStep(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Variable Speed Signal Step.
static GNEAdditional * buildCalibratorFlow(GNENet *net, bool allowUndoRedo, GNEAdditional *calibratorParent, GNEDemandElement *route, GNEDemandElement *vType, const std::string &vehsPerHour, const std::string &speed, const RGBColor &color, const std::string &departLane, const std::string &departPos, const std::string &departSpeed, const std::string &arrivalLane, const std::string &arrivalPos, const std::string &arrivalSpeed, const std::string &line, int personNumber, int containerNumber, bool reroute, const std::string &departPosLat, const std::string &arrivalPosLat, SUMOTime begin, SUMOTime end)
builds a calibrator flow
static bool parseAndBuildRerouterRouteProbReroute(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Route Prob Reroute.
static bool parseAndBuildRerouterDestProbReroute(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Destiny Prob Reroute.
static bool parseAndBuildAccess(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses values and adds access to the current bus stop.
Position getLanePos(const std::string &poiID, const std::string &laneID, double lanePos, double lanePosLat)
get lane position
static bool parseAndBuildDetectorEntry(GNENet *net, bool allowUndoRedo, const SUMOSAXAttributes &attrs, LastInsertedElement *insertedAdditionals)
Parses his values and builds a Entry detector.
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
const std::string & getID() const
get ID
virtual void updateGeometry()=0
update pre-computed geometry information
Position getPositionInView() const
Returns position of additional in view.
const std::string & getTagStr() const
get tag assigned to this object in string format
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
static bool canParse(const std::string &string)
true if a value of type T can be parsed from string
static bool lanesConsecutives(const std::vector< GNELane * > &lanes)
check if lanes are consecutives
static const double INVALID_POSITION
invalid double position
A lane area vehicles can halt at (netedit-version)
Definition: GNEBusStop.h:32
A lane area vehicles can halt at (netedit-version)
An Element which don't belongs to GNENet but has influency in the simulation.
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:49
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:399
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:723
void addChildElement(T *element)
add child element
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
double getLaneShapeLength() const
returns the length of the lane's shape
Definition: GNELane.cpp:762
GNEEdge * getParentEdge() const
get arent edge
Definition: GNELane.cpp:111
bool addPOI(const std::string &id, const std::string &type, const RGBColor &color, const Position &pos, bool geo, const std::string &lane, double posOverLane, double posLat, double layer, double angle, const std::string &imgFile, bool relativePath, double width, double height, bool ignorePruning=false)
Builds a POI using the given values and adds it to the container.
bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, bool relativePath, const PositionVector &shape, bool geo, bool fill, double lineWidth, bool ignorePruning=false)
Builds a polygon using the given values and adds it to the container.
void insertTAZElement(GNETAZElement *TAZElement)
Insert a TAZElement element int GNENet container.
void insertAdditional(GNEAdditional *additional)
Insert a additional element int GNENet container.
const std::map< SumoXMLTag, std::map< std::string, GNEShape * > > & getShapes() const
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:40
void disableUpdateGeometry()
disable update geometry of elements after inserting or removing an element in net
Definition: GNENet.cpp:3115
GNELane * retrieveLane(const std::string &id, bool failHard=true, bool checkVolatileChange=false)
get lane by id
Definition: GNENet.cpp:1337
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true) const
get edge by id
Definition: GNENet.cpp:1141
GNETAZElement * retrieveTAZElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named TAZElement.
Definition: GNENet.cpp:3001
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
retrieve all attribute carriers of Net
Definition: GNENet.cpp:130
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2316
GNEShape * retrieveShape(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named shape.
Definition: GNENet.cpp:2944
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2435
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2245
void enableUpdateGeometry()
Definition: GNENet.cpp:3109
const std::string & getID() const
get ID
A lane area vehicles can park at (netedit-version)
vehicle space used by GNEParkingAreas
void incRef(const std::string &debugMsg="")
Increarse reference.
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:31
virtual void setParameter(const std::string &key, const std::string &value)=0
Sets a parameter.
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNETAZElement.h:45
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform TAZElement changes
Definition: GNETAZ.h:33
bool hasDoubleParameters() const
return true if Tag correspond to an element that supports double parameters "key1=double1|key2=double...
bool hasParameters() const
return true if Tag correspond to an element that supports parameters "key1=value1|key2=value2|....
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:71
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
Definition: GNEUndoList.cpp:78
Representation of a vaporizer in netedit.
Definition: GNEVaporizer.h:31
GNEUndoList * getUndoList() const
get the undoList object
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
const std::string & getFileName() const
returns the current file name
static methods for processing the coordinates conversion for the current net
Definition: GeoConvHelper.h:53
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
The representation of a single edge during network building.
Definition: NBEdge.h:91
double getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:563
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:677
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:3954
static void interpretLaneID(const std::string &lane_id, std::string &edge_id, int &index)
parses edge-id and index from lane-id
Definition: NBHelpers.cpp:119
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
void set(double x, double y)
set positions x and y
Definition: Position.h:84
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:282
A list of positions.
static const RGBColor RED
named colors
Definition: RGBColor.h:180
StopPos
enum for stops
static StopPos checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
static bool isValidParameterKey(const std::string &value)
whether the given string is a valid key for a parameter
The XML-Handler for network loading.
Definition: ShapeHandler.h:47
virtual void myEndElement(int element)
Called when a closing tag occurs.
void setDefaults(const std::string &prefix, const RGBColor &color, const double layer, const bool fill=false)
set default values
Parameterised * getLastParameterised() const
get last parameterised object
const GeoConvHelper * myGeoConvHelper
geo-conversion to use during loading
Definition: ShapeHandler.h:127
static const double DEFAULT_LAYER_POI
Definition: Shape.h:43
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme, const std::string &routeValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:65
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:148