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