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.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Builds trigger objects for netedit
19 /****************************************************************************/
20 #include <config.h>
21 
23 #include <netedit/GNEViewNet.h>
24 #include <netedit/GNEUndoList.h>
25 #include <netedit/GNENet.h>
26 #include <utils/xml/NamespaceIDs.h>
27 
28 #include "GNEAdditionalHandler.h"
29 #include "GNEAccess.h"
30 #include "GNEBusStop.h"
31 #include "GNECalibrator.h"
32 #include "GNECalibratorFlow.h"
33 #include "GNEChargingStation.h"
34 #include "GNEClosingLaneReroute.h"
35 #include "GNEClosingReroute.h"
36 #include "GNEContainerStop.h"
37 #include "GNEDestProbReroute.h"
40 #include "GNELaneAreaDetector.h"
42 #include "GNEEntryExitDetector.h"
43 #include "GNEOverheadWire.h"
44 #include "GNEPOI.h"
45 #include "GNEParkingArea.h"
46 #include "GNEParkingAreaReroute.h"
47 #include "GNEParkingSpace.h"
48 #include "GNEPoly.h"
49 #include "GNERerouter.h"
50 #include "GNERerouterInterval.h"
51 #include "GNERerouterSymbol.h"
52 #include "GNERouteProbReroute.h"
53 #include "GNERouteProbe.h"
54 #include "GNETAZ.h"
55 #include "GNETAZSourceSink.h"
56 #include "GNETractionSubstation.h"
57 #include "GNEVaporizer.h"
58 #include "GNEVariableSpeedSign.h"
61 
62 
63 // ===========================================================================
64 // GNEAdditionalHandler method definitions
65 // ===========================================================================
66 
67 GNEAdditionalHandler::GNEAdditionalHandler(GNENet* net, const bool allowUndoRedo, const bool overwrite) :
68  myNet(net),
69  myAllowUndoRedo(allowUndoRedo),
70  myOverwrite(overwrite) {
71 }
72 
73 
75 }
76 
77 
78 void
79 GNEAdditionalHandler::buildBusStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id,
80  const std::string& laneID, const double startPos, const double endPos, const std::string& name,
81  const std::vector<std::string>& lines, const int personCapacity, const double parkingLength,
82  const RGBColor& color, const bool friendlyPosition, const Parameterised::Map& parameters) {
83  // check conditions
87  // get netedit parameters
88  NeteditParameters neteditParameters(sumoBaseObject);
89  // get lane
90  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
91  // check lane
92  if (lane == nullptr) {
94  } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
96  } else if (personCapacity < 0) {
98  } else if (parkingLength < 0) {
100  } else {
101  // build busStop
102  GNEAdditional* busStop = new GNEBusStop(SUMO_TAG_BUS_STOP, id, lane, myNet, startPos, endPos, name, lines, personCapacity,
103  parkingLength, color, friendlyPosition, parameters);
104  // insert depending of allowUndoRedo
105  if (myAllowUndoRedo) {
106  myNet->getViewNet()->getUndoList()->begin(busStop, TL("add bus stop '") + id + "'");
108  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(busStop, true), true);
109  myNet->getViewNet()->getUndoList()->end();
110  } else {
112  lane->addChildElement(busStop);
113  busStop->incRef("buildBusStop");
114  }
115  }
116  } else {
118  }
119 }
120 
121 
122 void
124  const std::string& laneID, const double startPos, const double endPos, const std::string& name,
125  const std::vector<std::string>& lines, const int personCapacity, const double parkingLength,
126  const RGBColor& color, const bool friendlyPosition, const Parameterised::Map& parameters) {
127  // check conditions
131  // get netedit parameters
132  NeteditParameters neteditParameters(sumoBaseObject);
133  // get lane
134  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
135  // check lane
136  if (lane == nullptr) {
138  } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
140  } else if (personCapacity < 0) {
142  } else if (parkingLength < 0) {
144  } else {
145  // build trainStop
146  GNEAdditional* trainStop = new GNEBusStop(SUMO_TAG_TRAIN_STOP, id, lane, myNet, startPos, endPos, name, lines, personCapacity,
147  parkingLength, color, friendlyPosition, parameters);
148  // insert depending of allowUndoRedo
149  if (myAllowUndoRedo) {
150  myNet->getViewNet()->getUndoList()->begin(trainStop, TL("add train stop '") + id + "'");
152  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(trainStop, true), true);
153  myNet->getViewNet()->getUndoList()->end();
154  } else {
156  lane->addChildElement(trainStop);
157  trainStop->incRef("buildTrainStop");
158  }
159  }
160  } else {
162  }
163 }
164 
165 
166 void
167 GNEAdditionalHandler::buildAccess(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID,
168  const std::string& pos, const double length, const bool friendlyPos, const Parameterised::Map& parameters) {
169  // get netedit parameters
170  NeteditParameters neteditParameters(sumoBaseObject);
171  // get lane
172  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
173  // get busStop (or trainStop)
174  GNEAdditional* busStop = getAdditionalParent(sumoBaseObject, SUMO_TAG_BUS_STOP);
175  if (busStop == nullptr) {
176  busStop = getAdditionalParent(sumoBaseObject, SUMO_TAG_TRAIN_STOP);
177  }
178  // pos double
179  bool validPos = true;
180  double posDouble = 0;
181  if (lane) {
182  if (GNEAttributeCarrier::canParse<double>(pos)) {
183  posDouble = GNEAttributeCarrier::parse<double>(pos);
184  validPos = checkLanePosition(posDouble, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos);
185  } else if (pos == "random" || pos == "doors") {
186  posDouble = INVALID_DOUBLE;
187  } else if (pos.empty()) {
188  posDouble = 0;
189  } else {
190  validPos = false;
191  }
192  }
193  // Check if busStop parent and lane is correct
194  if (lane == nullptr) {
196  } else if (busStop == nullptr) {
198  } else if (!validPos) {
200  } else if ((length != -1) && (length < 0)) {
202  } else if (!accessCanBeCreated(busStop, lane->getParentEdge())) {
203  WRITE_WARNING(TL("Could not build access in netedit; busStop parent already owns an access in the edge '") + lane->getParentEdge()->getID() + "'");
204  } else if (!lane->allowPedestrians()) {
205  WRITE_WARNING(TLF("Could not build access in netedit; The lane '%' doesn't support pedestrians", lane->getID()));
206  } else {
207  // build access
208  GNEAdditional* access = new GNEAccess(busStop, lane, myNet, posDouble, pos, friendlyPos, length, parameters);
209  // insert depending of allowUndoRedo
210  if (myAllowUndoRedo) {
211  myNet->getViewNet()->getUndoList()->begin(access, TL("add access in '") + busStop->getID() + "'");
213  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(access, true), true);
214  myNet->getViewNet()->getUndoList()->end();
215  } else {
217  lane->addChildElement(access);
218  busStop->addChildElement(access);
219  access->incRef("buildAccess");
220  }
221  }
222 }
223 
224 
225 void
226 GNEAdditionalHandler::buildContainerStop(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID,
227  const double startPos, const double endPos, const std::string& name, const std::vector<std::string>& lines, const int containerCapacity,
228  const double parkingLength, const RGBColor& color, const bool friendlyPosition, const Parameterised::Map& parameters) {
229  // check conditions
232  } else if (checkDuplicatedID({SUMO_TAG_CONTAINER_STOP}, id)) {
233  // get netedit parameters
234  NeteditParameters neteditParameters(sumoBaseObject);
235  // get lane
236  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
237  // check lane
238  if (lane == nullptr) {
240  } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
242  } else if (containerCapacity < 0) {
244  } else if (parkingLength < 0) {
246  } else {
247  // build containerStop
248  GNEAdditional* containerStop = new GNEContainerStop(id, lane, myNet, startPos, endPos, name, lines, containerCapacity, parkingLength,
249  color, friendlyPosition, parameters);
250  // insert depending of allowUndoRedo
251  if (myAllowUndoRedo) {
252  myNet->getViewNet()->getUndoList()->begin(containerStop, TL("add container stop '") + id + "'");
254  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(containerStop, true), true);
255  myNet->getViewNet()->getUndoList()->end();
256  } else {
257  myNet->getAttributeCarriers()->insertAdditional(containerStop);
258  lane->addChildElement(containerStop);
259  containerStop->incRef("buildContainerStop");
260  }
261  }
262  } else {
264  }
265 }
266 
267 
268 void
270  const std::string& laneID, const double startPos, const double endPos, const std::string& name, const double chargingPower,
271  const double efficiency, const bool chargeInTransit, const SUMOTime chargeDelay, const std::string& chargeType,
272  const SUMOTime waitingTime, const bool friendlyPosition, const std::string& /* parkingAreaID */, const Parameterised::Map& parameters) {
273  // check conditions
276  } else if (checkDuplicatedID({SUMO_TAG_CHARGING_STATION}, id)) {
277  // get netedit parameters
278  NeteditParameters neteditParameters(sumoBaseObject);
279  // get lane
280  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
281  // check lane
282  if (lane == nullptr) {
284  } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
286  } else if (chargingPower < 0) {
288  } else if (chargeDelay < 0) {
290  } else {
291  // build chargingStation
292  GNEAdditional* chargingStation = new GNEChargingStation(id, lane, myNet, startPos, endPos, name, chargingPower, efficiency, chargeInTransit,
293  chargeDelay, chargeType, waitingTime, friendlyPosition, parameters);
294  // insert depending of allowUndoRedo
295  if (myAllowUndoRedo) {
296  myNet->getViewNet()->getUndoList()->begin(chargingStation, TL("add charging station '") + id + "'");
298  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(chargingStation, true), true);
299  myNet->getViewNet()->getUndoList()->end();
300  } else {
301  myNet->getAttributeCarriers()->insertAdditional(chargingStation);
302  lane->addChildElement(chargingStation);
303  chargingStation->incRef("buildChargingStation");
304  }
305  }
306  } else {
308  }
309 
310 }
311 
312 
313 void
314 GNEAdditionalHandler::buildParkingArea(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID,
315  const double startPos, const double endPos, const std::string& departPos, const std::string& name,
316  const std::vector<std::string>& badges, const bool friendlyPosition, const int roadSideCapacity, const bool onRoad,
317  const double width, const double length, const double angle, const bool lefthand, const Parameterised::Map& parameters) {
318  // check conditions
321  } else if (checkDuplicatedID({SUMO_TAG_PARKING_AREA}, id)) {
322  // get netedit parameters
323  NeteditParameters neteditParameters(sumoBaseObject);
324  // get lane
325  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
326  // get departPos double
327  const double departPosDouble = GNEAttributeCarrier::canParse<double>(departPos) ? GNEAttributeCarrier::parse<double>(departPos) : 0;
328  // check lane
329  if (lane == nullptr) {
331  } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
333  } else if (roadSideCapacity < 0) {
335  } else if (width < 0) {
337  } else if (length < 0) {
339  } else if ((departPosDouble < 0) || (departPosDouble > lane->getParentEdge()->getNBEdge()->getFinalLength())) {
340  writeError(TLF("Could not build parking area with ID '%' in netedit; Invalid departPos over lane.", id));
341  } else {
342  // build parkingArea
343  GNEAdditional* parkingArea = new GNEParkingArea(id, lane, myNet, startPos, endPos, GNEAttributeCarrier::canParse<double>(departPos) ? departPos : "",
344  name, badges, friendlyPosition, roadSideCapacity, onRoad,
345  (width == 0) ? SUMO_const_laneWidth : width, length, angle, lefthand, parameters);
346  // insert depending of allowUndoRedo
347  if (myAllowUndoRedo) {
348  myNet->getViewNet()->getUndoList()->begin(parkingArea, TL("add parking area '") + id + "'");
350  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingArea, true), true);
351  myNet->getViewNet()->getUndoList()->end();
352  } else {
354  lane->addChildElement(parkingArea);
355  parkingArea->incRef("buildParkingArea");
356  }
357  }
358  } else {
360  }
361 }
362 
363 
364 void
365 GNEAdditionalHandler::buildParkingSpace(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const double x, const double y, const double z,
366  const std::string& name, const std::string& width, const std::string& length, const std::string& angle, const double slope,
367  const Parameterised::Map& parameters) {
368  // check width and heights
369  if (!width.empty() && !GNEAttributeCarrier::canParse<double>(width)) {
370  writeError(TL("Could not build parking space in netedit; attribute width cannot be parse to float."));
371  } else if (!length.empty() && !GNEAttributeCarrier::canParse<double>(length)) {
372  writeError(TL("Could not build parking space in netedit; attribute length cannot be parse to float."));
373  } else if (!angle.empty() && !GNEAttributeCarrier::canParse<double>(angle)) {
374  writeError(TL("Could not build parking space in netedit; attribute angle cannot be parse to float."));
375  } else {
376  // get netedit parameters
377  NeteditParameters neteditParameters(sumoBaseObject);
378  // get lane
379  GNEAdditional* parkingArea = getAdditionalParent(sumoBaseObject, SUMO_TAG_PARKING_AREA);
380  // get double values
381  const double widthDouble = width.empty() ? 0 : GNEAttributeCarrier::parse<double>(width);
382  const double lengthDouble = length.empty() ? 0 : GNEAttributeCarrier::parse<double>(length);
383  // check lane
384  if (parkingArea == nullptr) {
386  } else if (widthDouble < 0) {
388  } else if (lengthDouble < 0) {
390  } else {
391  // build parkingSpace
392  GNEAdditional* parkingSpace = new GNEParkingSpace(myNet, parkingArea, Position(x, y, z), width, length, angle, slope, name, parameters);
393  // insert depending of allowUndoRedo
394  if (myAllowUndoRedo) {
395  myNet->getViewNet()->getUndoList()->begin(parkingSpace, TL("add parking space in '") + parkingArea->getID() + "'");
397  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingSpace, true), true);
398  myNet->getViewNet()->getUndoList()->end();
399  } else {
400  myNet->getAttributeCarriers()->insertAdditional(parkingSpace);
401  parkingArea->addChildElement(parkingSpace);
402  parkingSpace->incRef("buildParkingSpace");
403  }
404  // update geometry (due boundaries)
405  parkingSpace->updateGeometry();
406  }
407  }
408 }
409 
410 
411 void
412 GNEAdditionalHandler::buildE1Detector(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID,
413  const double position, const SUMOTime period, const std::string& file, const std::vector<std::string>& vehicleTypes, const std::string& name,
414  const bool friendlyPos, const Parameterised::Map& parameters) {
415  // check conditions
418  } else if (checkDuplicatedID({SUMO_TAG_INDUCTION_LOOP}, id)) {
419  // get netedit parameters
420  NeteditParameters neteditParameters(sumoBaseObject);
421  // get lane
422  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
423  // check lane
424  if (lane == nullptr) {
426  } else if (!checkLanePosition(position, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
428  } else if (period < 0) {
430  } else if (!SUMOXMLDefinitions::isValidFilename(file)) {
432  } else if (!vehicleTypes.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(vehicleTypes)) {
434  } else {
435  // build E1
436  GNEAdditional* detectorE1 = new GNEInductionLoopDetector(id, lane, myNet, position, period, file, vehicleTypes, name, friendlyPos, parameters);
437  // insert depending of allowUndoRedo
438  if (myAllowUndoRedo) {
439  myNet->getViewNet()->getUndoList()->begin(detectorE1, TL("add induction loop '") + id + "'");
441  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1, true), true);
442  myNet->getViewNet()->getUndoList()->end();
443  } else {
445  lane->addChildElement(detectorE1);
446  detectorE1->incRef("buildDetectorE1");
447  }
448  }
449  } else {
451  }
452 }
453 
454 
455 void
456 GNEAdditionalHandler::buildSingleLaneDetectorE2(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID,
457  const double pos, const double length, const SUMOTime period, const std::string& trafficLight, const std::string& filename, const std::vector<std::string>& vehicleTypes,
458  const std::string& name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos,
459  const Parameterised::Map& parameters) {
460  // check conditions
464  // get netedit parameters
465  NeteditParameters neteditParameters(sumoBaseObject);
466  // get lane
467  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
468  // check lane
469  if (lane == nullptr) {
471  } else if (!checkLanePosition(pos, length, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
473  } else if (length < 0) {
475  } else if ((period != -1) && (period < 0)) {
477  } else if ((trafficLight.size() > 0) && !(SUMOXMLDefinitions::isValidNetID(trafficLight))) {
478  // temporal
479  writeError(TLF("Could not build lane area detector with ID '%' in netedit; invalid traffic light ID.", id));
480  } else if (timeThreshold < 0) {
482  } else if (speedThreshold < 0) {
484  } else if (jamThreshold < 0) {
486  } else if (timeThreshold < 0) {
488  } else if (speedThreshold < 0) {
490  } else if (jamThreshold < 0) {
492  } else if (!SUMOXMLDefinitions::isValidFilename(filename)) {
494  } else if (!vehicleTypes.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(vehicleTypes)) {
496  } else {
497  // build E2 single lane
498  GNEAdditional* detectorE2 = new GNELaneAreaDetector(
499  id, lane, myNet, pos, length, period, trafficLight, filename,
500  vehicleTypes, name, timeThreshold, speedThreshold, jamThreshold,
501  friendlyPos, parameters);
502  // insert depending of allowUndoRedo
503  if (myAllowUndoRedo) {
504  myNet->getViewNet()->getUndoList()->begin(detectorE2, TL("add lane area detector '") + id + "'");
506  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
507  myNet->getViewNet()->getUndoList()->end();
508  } else {
510  lane->addChildElement(detectorE2);
511  detectorE2->incRef("buildDetectorE2");
512  }
513  }
514  } else {
516  }
517 }
518 
519 
520 void
521 GNEAdditionalHandler::buildMultiLaneDetectorE2(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::vector<std::string>& laneIDs,
522  const double pos, const double endPos, const SUMOTime period, const std::string& trafficLight, const std::string& filename, const std::vector<std::string>& vehicleTypes,
523  const std::string& name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos,
524  const Parameterised::Map& parameters) {
525  // check conditions
529  // get netedit parameters
530  NeteditParameters neteditParameters(sumoBaseObject);
531  // get lanes
532  const auto lanes = parseLanes(SUMO_TAG_LANE_AREA_DETECTOR, laneIDs);
533  // check lanes
534  if (lanes.size() > 0) {
535  // calculate path
537  writeError(TLF("Could not build lane area detector with ID '%' in netedit; Lanes aren't consecutives.", id));
538  } else if (!checkMultiLanePosition(
539  pos, lanes.front()->getParentEdge()->getNBEdge()->getFinalLength(),
540  endPos, lanes.back()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
542  } else if ((period != -1) && (period < 0)) {
544  } else if ((trafficLight.size() > 0) && !(SUMOXMLDefinitions::isValidNetID(trafficLight))) {
545  // temporal
546  writeError(TLF("Could not build lane area detector with ID '%' in netedit; invalid traffic light ID.", id));
547  } else if (timeThreshold < 0) {
549  } else if (speedThreshold < 0) {
551  } else if (jamThreshold < 0) {
553  } else if (!SUMOXMLDefinitions::isValidFilename(filename)) {
555  } else if (!vehicleTypes.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(vehicleTypes)) {
557  } else {
558  // build E2 multilane detector
559  GNEAdditional* detectorE2 = new GNELaneAreaDetector(
560  id, lanes, myNet, pos, endPos, period, trafficLight, filename,
561  vehicleTypes, name, timeThreshold, speedThreshold, jamThreshold,
562  friendlyPos, parameters);
563  // insert depending of allowUndoRedo
564  if (myAllowUndoRedo) {
565  myNet->getViewNet()->getUndoList()->begin(detectorE2, TL("add lane area detector '") + id + "'");
567  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
568  myNet->getViewNet()->getUndoList()->end();
569  } else {
571  for (const auto& lane : lanes) {
572  lane->addChildElement(detectorE2);
573  }
574  detectorE2->incRef("buildDetectorE2Multilane");
575  }
576  }
577  } else {
579  }
580  } else {
582  }
583 }
584 
585 
586 void
587 GNEAdditionalHandler::buildDetectorE3(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const Position& pos, const SUMOTime period,
588  const std::string& filename, const std::vector<std::string>& vehicleTypes, const std::string& name, const SUMOTime timeThreshold,
589  const double speedThreshold, const bool expectedArrival, const Parameterised::Map& parameters) {
590  // check conditions
593  } else if (period < 0) {
595  } else if (timeThreshold < 0) {
597  } else if (speedThreshold < 0) {
599  } else if (!SUMOXMLDefinitions::isValidFilename(filename)) {
601  } else if (!vehicleTypes.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(vehicleTypes)) {
604  // get netedit parameters
605  NeteditParameters neteditParameters(sumoBaseObject);
606  // build E3
607  GNEAdditional* E3 = new GNEMultiEntryExitDetector(id, myNet, pos, period, filename, vehicleTypes, name, timeThreshold, speedThreshold, expectedArrival, parameters);
608  // insert depending of allowUndoRedo
609  if (myAllowUndoRedo) {
610  myNet->getViewNet()->getUndoList()->begin(E3, TL("add entry-exit detector '") + id + "'");
612  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(E3, true), true);
613  myNet->getViewNet()->getUndoList()->end();
614  } else {
616  E3->incRef("buildDetectorE3");
617  }
618  } else {
620  }
621 }
622 
623 
624 void
625 GNEAdditionalHandler::buildDetectorEntry(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID, const double pos,
626  const bool friendlyPos, const Parameterised::Map& parameters) {
627  // get lane
628  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
629  // get E3 parent
631  // Check if Detector E3 parent and lane is correct
632  if (lane == nullptr) {
634  } else if (E3 == nullptr) {
636  } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
638  } else {
639  // get netedit parameters
640  NeteditParameters neteditParameters(sumoBaseObject);
641  // build entry instant
642  GNEAdditional* entry = new GNEEntryExitDetector(SUMO_TAG_DET_ENTRY, myNet, E3, lane, pos, friendlyPos, parameters);
643  // insert depending of allowUndoRedo
644  if (myAllowUndoRedo) {
645  myNet->getViewNet()->getUndoList()->begin(entry, TL("add entry detector in '") + E3->getID() + "'");
647  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(entry, true), true);
648  myNet->getViewNet()->getUndoList()->end();
649  } else {
651  lane->addChildElement(entry);
652  E3->addChildElement(entry);
653  entry->incRef("buildDetectorEntry");
654  }
655  }
656 }
657 
658 
659 void
660 GNEAdditionalHandler::buildDetectorExit(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID, const double pos,
661  const bool friendlyPos, const Parameterised::Map& parameters) {
662  // get lane
663  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
664  // get E3 parent
666  // Check if Detector E3 parent and lane is correct
667  if (lane == nullptr) {
669  } else if (E3 == nullptr) {
671  } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
673  } else {
674  // get netedit parameters
675  NeteditParameters neteditParameters(sumoBaseObject);
676  // build exit instant
677  GNEAdditional* exit = new GNEEntryExitDetector(SUMO_TAG_DET_EXIT, myNet, E3, lane, pos, friendlyPos, parameters);
678  // insert depending of allowUndoRedo
679  if (myAllowUndoRedo) {
680  myNet->getViewNet()->getUndoList()->begin(exit, TL("add exit detector in '") + E3->getID() + "'");
682  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(exit, true), true);
683  myNet->getViewNet()->getUndoList()->end();
684  } else {
686  lane->addChildElement(exit);
687  E3->addChildElement(exit);
688  exit->incRef("buildDetectorExit");
689  }
690  }
691 }
692 
693 
694 void
695 GNEAdditionalHandler::buildDetectorE1Instant(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID, double pos,
696  const std::string& filename, const std::vector<std::string>& vehicleTypes, const std::string& name, const bool friendlyPos, const Parameterised::Map& parameters) {
697  // check conditions
701  // get netedit parameters
702  NeteditParameters neteditParameters(sumoBaseObject);
703  // get lane
704  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
705  // check lane
706  if (lane == nullptr) {
708  } else if (!SUMOXMLDefinitions::isValidFilename(filename)) {
710  } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
712  } else {
713  // build E1 instant
714  GNEAdditional* detectorE1Instant = new GNEInstantInductionLoopDetector(id, lane, myNet, pos, filename, vehicleTypes, name, friendlyPos, parameters);
715  // insert depending of allowUndoRedo
716  if (myAllowUndoRedo) {
717  myNet->getViewNet()->getUndoList()->begin(detectorE1Instant, TL("add instant induction loop '") + id + "'");
719  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1Instant, true), true);
720  myNet->getViewNet()->getUndoList()->end();
721  } else {
722  myNet->getAttributeCarriers()->insertAdditional(detectorE1Instant);
723  lane->addChildElement(detectorE1Instant);
724  detectorE1Instant->incRef("buildDetectorE1Instant");
725  }
726  }
727  } else {
729  }
730 }
731 
732 
733 void
734 GNEAdditionalHandler::buildLaneCalibrator(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& laneID, const double pos,
735  const std::string& name, const std::string& outfile, const SUMOTime period, const std::string& routeprobeID, const double jamThreshold, const std::vector<std::string>& vTypes,
736  const Parameterised::Map& parameters) {
737  // get lane
738  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
739  // get routeProbe
740  GNEAdditional* routeProbe = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_ROUTEPROBE, routeprobeID, false);
741  // check conditions
746  } else if ((routeprobeID.size() > 0) && (routeProbe == nullptr)) {
748  } else if (lane == nullptr) {
750  } else {
751  // get netedit parameters
752  NeteditParameters neteditParameters(sumoBaseObject);
753  // check lane
754  if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), false)) {
756  } else if (period < 0) {
758  } else if (jamThreshold < 0) {
760  } else {
761  // build Calibrator
762  GNEAdditional* calibrator = (routeProbe == nullptr) ?
763  new GNECalibrator(id, myNet, lane, pos, period, name, outfile, jamThreshold, vTypes, parameters) :
764  new GNECalibrator(id, myNet, lane, pos, period, name, outfile, routeProbe, jamThreshold, vTypes, parameters);
765  // insert depending of allowUndoRedo
766  if (myAllowUndoRedo) {
767  myNet->getViewNet()->getUndoList()->begin(calibrator, TL("add lane calibrator '") + id + "'");
769  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
770  myNet->getViewNet()->getUndoList()->end();
771  // center after creation
772  if (neteditParameters.centerAfterCreation) {
773  myNet->getViewNet()->centerTo(calibrator->getPositionInView(), false);
774  }
775  } else {
777  lane->addChildElement(calibrator);
778  if (routeProbe) {
779  routeProbe->addChildElement(calibrator);
780  }
781  calibrator->incRef("buildCalibrator");
782  }
783  }
784  }
785 }
786 
787 
788 void
789 GNEAdditionalHandler::buildEdgeCalibrator(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& edgeID, const double pos,
790  const std::string& name, const std::string& outfile, const SUMOTime period, const std::string& routeprobeID, const double jamThreshold, const std::vector<std::string>& vTypes,
791  const Parameterised::Map& parameters) {
792  // get edge
793  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
794  // get routeProbe
795  GNEAdditional* routeProbe = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_ROUTEPROBE, routeprobeID, false);
796  // check conditions
801  } else if ((routeprobeID.size() > 0) && (routeProbe == nullptr)) {
803  } else if (edge == nullptr) {
805  } else {
806  // get netedit parameters
807  NeteditParameters neteditParameters(sumoBaseObject);
808  if (!checkLanePosition(pos, 0, edge->getLanes().front()->getParentEdge()->getNBEdge()->getFinalLength(), false)) {
810  } else if (period < 0) {
812  } else if (jamThreshold < 0) {
814  } else {
815  // build Calibrator
816  GNEAdditional* calibrator = (routeProbe == nullptr) ?
817  new GNECalibrator(id, myNet, edge, pos, period, name, outfile, jamThreshold, vTypes, parameters) :
818  new GNECalibrator(id, myNet, edge, pos, period, name, outfile, routeProbe, jamThreshold, vTypes, parameters);
819  // insert depending of allowUndoRedo
820  if (myAllowUndoRedo) {
821  myNet->getViewNet()->getUndoList()->begin(calibrator, TL("add calibrator '") + id + "'");
823  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
824  myNet->getViewNet()->getUndoList()->end();
825  // center after creation
826  if (neteditParameters.centerAfterCreation) {
827  myNet->getViewNet()->centerTo(calibrator->getPositionInView(), false);
828  }
829  } else {
831  edge->addChildElement(calibrator);
832  if (routeProbe) {
833  routeProbe->addChildElement(calibrator);
834  }
835  calibrator->incRef("buildCalibrator");
836  }
837  }
838  }
839 }
840 
841 
842 void
844  // get vType
845  GNEDemandElement* vType = myNet->getAttributeCarriers()->retrieveDemandElement(SUMO_TAG_VTYPE, vehicleParameter.vtypeid.empty() ? DEFAULT_VTYPE_ID : vehicleParameter.vtypeid, false);
846  // get route
848  // get calibrator parent
850  // check parents
851  if (vType == nullptr) {
853  } else if (route == nullptr) {
855  } else if (calibrator == nullptr) {
857  } else {
858  // create calibrator flow
859  GNEAdditional* flow = new GNECalibratorFlow(calibrator, vType, route, vehicleParameter);
860  // insert depending of allowUndoRedo
861  if (myAllowUndoRedo) {
862  myNet->getViewNet()->getUndoList()->begin(flow, TL("add calibrator flow in '") + calibrator->getID() + "'");
864  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(flow, true), true);
865  myNet->getViewNet()->getUndoList()->end();
866  } else {
867  calibrator->addChildElement(flow);
868  route->addChildElement(flow);
869  vType->addChildElement(flow);
870  flow->incRef("buildCalibratorFlow");
871  }
872  }
873 }
874 
875 
876 void
877 GNEAdditionalHandler::buildRerouter(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const Position& pos,
878  const std::vector<std::string>& edgeIDs, const double prob, const std::string& name,
879  const bool off, const bool optional, const SUMOTime timeThreshold,
880  const std::vector<std::string>& vTypes, const Parameterised::Map& parameters) {
881  // check conditions
884  } else if (prob < 0) {
886  } else if (timeThreshold < 0) {
888  } else if (!vTypes.empty() && !SUMOXMLDefinitions::isValidListOfTypeID(vTypes)) {
890  } else if (checkDuplicatedID({SUMO_TAG_REROUTER}, id)) {
891  // get netedit parameters
892  NeteditParameters neteditParameters(sumoBaseObject);
893  // parse edges
894  std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_REROUTER, edgeIDs);
895  // check edges
896  if (edges.size() > 0) {
897  GNEAdditional* rerouter = nullptr;
898  // continue depending of position
899  if (pos == Position::INVALID) {
900  if (edges.size() > 0) {
901  PositionVector laneShape = edges.front()->getLanes().front()->getLaneShape();
902  // move to side
903  laneShape.move2side(3);
904  // create rerouter
905  rerouter = new GNERerouter(id, myNet, laneShape.positionAtOffset2D(laneShape.length2D() - 6), name, prob, off, optional, timeThreshold, vTypes, parameters);
906  } else {
907  rerouter = new GNERerouter(id, myNet, Position(0, 0), name, prob, off, optional, timeThreshold, vTypes, parameters);
908  }
909  } else {
910  rerouter = new GNERerouter(id, myNet, pos, name, prob, off, optional, timeThreshold, vTypes, parameters);
911  }
912  // create rerouter Symbols
913  std::vector<GNEAdditional*> rerouterSymbols;
914  for (const auto& edge : edges) {
915  rerouterSymbols.push_back(new GNERerouterSymbol(rerouter, edge));
916  }
917  // insert depending of allowUndoRedo
918  if (myAllowUndoRedo) {
919  myNet->getViewNet()->getUndoList()->begin(rerouter, TL("add rerouter '") + id + "'");
921  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouter, true), true);
922  // add symbols
923  for (const auto& rerouterSymbol : rerouterSymbols) {
924  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterSymbol, true), true);
925  }
926  myNet->getViewNet()->getUndoList()->end();
927  } else {
929  rerouter->incRef("buildRerouter");
930  // add symbols into rerouter
931  for (const auto& rerouterSymbol : rerouterSymbols) {
932  rerouter->addChildElement(rerouterSymbol);
933  }
934  // add symbols into edges
935  for (int i = 0; i < (int)edges.size(); i++) {
936  edges.at(i)->addChildElement(rerouterSymbols.at(i));
937  }
938  }
939  }
940  } else {
942  }
943 }
944 
945 
946 void
948  // get rerouter parent
949  GNEAdditional* rerouter = getAdditionalParent(sumoBaseObject, SUMO_TAG_REROUTER);
950  // check if rerouter exist
951  if (rerouter == nullptr) {
953  } else if (begin < 0) {
955  } else if (end < 0) {
957  } else if (end < begin) {
958  writeError(TLF("Could not build interval with ID '%' in netedit; begin is greater than end.", rerouter->getID()));
959  } else {
960  // check if new interval will produce a overlapping
961  if (checkOverlappingRerouterIntervals(rerouter, begin, end)) {
962  // create rerouter interval and add it into rerouter parent
963  GNEAdditional* rerouterInterval = new GNERerouterInterval(rerouter, begin, end);
964  // insert depending of allowUndoRedo
965  if (myAllowUndoRedo) {
966  myNet->getViewNet()->getUndoList()->begin(rerouterInterval, TL("add rerouter interval in '") + rerouter->getID() + "'");
968  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterInterval, true), true);
969  myNet->getViewNet()->getUndoList()->end();
970  } else {
971  rerouter->addChildElement(rerouterInterval);
972  rerouterInterval->incRef("buildRerouterInterval");
973  }
974  } else {
975  writeError(TLF("Could not build interval with begin '%' and end '%' in '%' due overlapping.", toString(begin), toString(end), rerouter->getID()));
976  }
977  }
978 }
979 
980 
981 void
982 GNEAdditionalHandler::buildClosingLaneReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& closedLaneID, SVCPermissions permissions) {
983  // get rerouter interval parent
984  GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
985  // get closed lane
986  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(closedLaneID, false);
987  // check parents
988  if (lane == nullptr) {
990  } else if (rerouterInterval == nullptr) {
992  } else {
993  // create closing lane reroute
994  GNEAdditional* closingLaneReroute = new GNEClosingLaneReroute(rerouterInterval, lane, permissions);
995  // add it to interval parent depending of allowUndoRedo
996  if (myAllowUndoRedo) {
997  myNet->getViewNet()->getUndoList()->begin(closingLaneReroute, TL("add closing lane reroute in '") + lane->getID() + "'");
999  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingLaneReroute, true), true);
1000  myNet->getViewNet()->getUndoList()->end();
1001  } else {
1002  rerouterInterval->addChildElement(closingLaneReroute);
1003  closingLaneReroute->incRef("buildClosingLaneReroute");
1004  }
1005  }
1006 }
1007 
1008 
1009 void
1010 GNEAdditionalHandler::buildClosingReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& closedEdgeID, SVCPermissions permissions) {
1011  // get rerouter interval parent
1012  GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1013  // get closed edge
1014  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(closedEdgeID, false);
1015  // check parents
1016  if (edge == nullptr) {
1018  } else if (rerouterInterval == nullptr) {
1020  } else {
1021  // create closing reroute
1022  GNEAdditional* closingLaneReroute = new GNEClosingReroute(rerouterInterval, edge, permissions);
1023  // add it to interval parent depending of allowUndoRedo
1024  if (myAllowUndoRedo) {
1025  myNet->getViewNet()->getUndoList()->begin(closingLaneReroute, TL("add closing reroute in '") + edge->getID() + "'");
1027  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingLaneReroute, true), true);
1028  myNet->getViewNet()->getUndoList()->end();
1029  } else {
1030  rerouterInterval->addChildElement(closingLaneReroute);
1031  closingLaneReroute->incRef("buildClosingLaneReroute");
1032  }
1033  }
1034 }
1035 
1036 void
1037 GNEAdditionalHandler::buildDestProbReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newEdgeDestinationID, const double probability) {
1038  // get rerouter interval parent
1039  GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1040  // get edge
1041  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(newEdgeDestinationID, false);
1042  // check parents
1043  if (edge == nullptr) {
1045  } else if (rerouterInterval == nullptr) {
1047  } else {
1048  // create dest probability reroute
1049  GNEAdditional* destProbReroute = new GNEDestProbReroute(rerouterInterval, edge, probability);
1050  // add it to interval parent depending of allowUndoRedo
1051  if (myAllowUndoRedo) {
1052  myNet->getViewNet()->getUndoList()->begin(destProbReroute, TL("add dest prob reroute in '") + edge->getID() + "'");
1054  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(destProbReroute, true), true);
1055  myNet->getViewNet()->getUndoList()->end();
1056  } else {
1057  rerouterInterval->addChildElement(destProbReroute);
1058  destProbReroute->incRef("builDestProbReroute");
1059  }
1060  }
1061 }
1062 
1063 
1064 void
1065 GNEAdditionalHandler::buildParkingAreaReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newParkignAreaID, const double probability, const bool visible) {
1066  // get rerouter interval parent
1067  GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1068  // get parking area
1069  GNEAdditional* parkingArea = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, newParkignAreaID, false);
1070  // check parents
1071  if (parkingArea == nullptr) {
1073  } else if (rerouterInterval == nullptr) {
1075  } else {
1076  // create parking area reroute
1077  GNEAdditional* parkingAreaReroute = new GNEParkingAreaReroute(rerouterInterval, parkingArea, probability, visible);
1078  // add it to interval parent depending of allowUndoRedo
1079  if (myAllowUndoRedo) {
1080  myNet->getViewNet()->getUndoList()->begin(parkingAreaReroute, TL("add parking area reroute in '") + parkingArea->getID() + "'");
1082  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingAreaReroute, true), true);
1083  myNet->getViewNet()->getUndoList()->end();
1084  } else {
1085  rerouterInterval->addChildElement(parkingAreaReroute);
1086  parkingAreaReroute->incRef("builParkingAreaReroute");
1087  }
1088  }
1089 }
1090 
1091 
1092 void
1093 GNEAdditionalHandler::buildRouteProbReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newRouteID, const double probability) {
1094  // get rerouter interval parent
1095  GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1096  // get route parent
1098  // check parents
1099  if (route == nullptr) {
1101  } else if (rerouterInterval == nullptr) {
1103  } else {
1104  // create rout prob reroute
1105  GNEAdditional* routeProbReroute = new GNERouteProbReroute(rerouterInterval, route, probability);
1106  // add it to interval parent depending of allowUndoRedo
1107  if (myAllowUndoRedo) {
1108  myNet->getViewNet()->getUndoList()->begin(routeProbReroute, TL("add route prob reroute in '") + route->getID() + "'");
1110  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbReroute, true), true);
1111  myNet->getViewNet()->getUndoList()->end();
1112  } else {
1113  rerouterInterval->addChildElement(routeProbReroute);
1114  routeProbReroute->incRef("buildRouteProbReroute");
1115  }
1116  }
1117 }
1118 
1119 
1120 void
1121 GNEAdditionalHandler::buildRouteProbe(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& edgeID, const SUMOTime period,
1122  const std::string& name, const std::string& file, const SUMOTime begin, const Parameterised::Map& parameters) {
1123  // check conditions
1126  } else if (checkDuplicatedID({SUMO_TAG_ROUTEPROBE}, id)) {
1127  // get netedit parameters
1128  NeteditParameters neteditParameters(sumoBaseObject);
1129  // get edge
1130  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1131  // check lane
1132  if (edge == nullptr) {
1134  } else if (period < 0) {
1136  } else if (begin < 0) {
1138  } else if (!SUMOXMLDefinitions::isValidFilename(file)) {
1140  } else {
1141  // build route probe
1142  GNEAdditional* routeProbe = new GNERouteProbe(id, myNet, edge, period, name, file, begin, parameters);
1143  // insert depending of allowUndoRedo
1144  if (myAllowUndoRedo) {
1145  myNet->getViewNet()->getUndoList()->begin(routeProbe, TL("add route probe '") + id + "'");
1147  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbe, true), true);
1148  myNet->getViewNet()->getUndoList()->end();
1149  // center after creation
1150  if (neteditParameters.centerAfterCreation) {
1151  myNet->getViewNet()->centerTo(routeProbe->getPositionInView(), false);
1152  }
1153  } else {
1155  edge->addChildElement(routeProbe);
1156  routeProbe->incRef("buildRouteProbe");
1157  }
1158  }
1159  } else {
1161  }
1162 }
1163 
1164 
1165 void
1166 GNEAdditionalHandler::buildVariableSpeedSign(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const Position& pos,
1167  const std::vector<std::string>& laneIDs, const std::string& name, const std::vector<std::string>& vTypes, const Parameterised::Map& parameters) {
1171  } else if (checkDuplicatedID({SUMO_TAG_VSS}, id)) {
1172  // get netedit parameters
1173  NeteditParameters neteditParameters(sumoBaseObject);
1174  // parse lanes
1175  std::vector<GNELane*> lanes = parseLanes(SUMO_TAG_VSS, laneIDs);
1176  // check lane
1177  if (lanes.size() > 0) {
1178  // check vTypes
1179  if (!vTypes.empty() && !checkListOfVehicleTypes(vTypes)) {
1181  } else {
1182  // create VSS
1183  GNEAdditional* variableSpeedSign = new GNEVariableSpeedSign(id, myNet, pos, name, vTypes, parameters);
1184  // create VSS Symbols
1185  std::vector<GNEAdditional*> VSSSymbols;
1186  for (const auto& lane : lanes) {
1187  VSSSymbols.push_back(new GNEVariableSpeedSignSymbol(variableSpeedSign, lane));
1188  }
1189  // insert depending of allowUndoRedo
1190  if (myAllowUndoRedo) {
1191  myNet->getViewNet()->getUndoList()->begin(variableSpeedSign, TL("add Variable Speed Sign '") + id + "'");
1193  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSign, true), true);
1194  for (const auto& VSSSymbol : VSSSymbols) {
1195  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(VSSSymbol, true), true);
1196  }
1197  myNet->getViewNet()->getUndoList()->end();
1198  } else {
1199  myNet->getAttributeCarriers()->insertAdditional(variableSpeedSign);
1200  variableSpeedSign->incRef("buildVariableSpeedSign");
1201  // add symbols into VSS
1202  for (const auto& VSSSymbol : VSSSymbols) {
1203  variableSpeedSign->addChildElement(VSSSymbol);
1204  }
1205  // add symbols into lanes
1206  for (int i = 0; i < (int)lanes.size(); i++) {
1207  lanes.at(i)->addChildElement(VSSSymbols.at(i));
1208  }
1209  }
1210  }
1211  }
1212  } else {
1214  }
1215 }
1216 
1217 
1218 void
1219 GNEAdditionalHandler::buildVariableSpeedSignStep(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const SUMOTime time, const std::string& speed) {
1220  // get VSS parent
1221  GNEAdditional* VSS = getAdditionalParent(sumoBaseObject, SUMO_TAG_VSS);
1222  // check lane
1223  if (VSS == nullptr) {
1225  } else if (time < 0) {
1227  } else {
1228  // create Variable Speed Sign
1229  GNEAdditional* variableSpeedSignStep = new GNEVariableSpeedSignStep(VSS, time, speed);
1230  // add it depending of allow undoRedo
1231  if (myAllowUndoRedo) {
1232  myNet->getViewNet()->getUndoList()->begin(variableSpeedSignStep, TL("add VSS Step in '") + VSS->getID() + "'");
1234  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSignStep, true), true);
1235  myNet->getViewNet()->getUndoList()->end();
1236  } else {
1237  VSS->addChildElement(variableSpeedSignStep);
1238  variableSpeedSignStep->incRef("buildVariableSpeedSignStep");
1239  }
1240  }
1241 }
1242 
1243 
1244 void
1245 GNEAdditionalHandler::buildVaporizer(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const SUMOTime beginTime,
1246  const SUMOTime endTime, const std::string& name, const Parameterised::Map& parameters) {
1247  // check conditions
1250  } else if (checkDuplicatedID({SUMO_TAG_VAPORIZER}, edgeID)) {
1251  // get netedit parameters
1252  NeteditParameters neteditParameters(sumoBaseObject);
1253  // get edge
1254  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1255  // check lane
1256  if (edge == nullptr) {
1258  } else if (beginTime < 0) {
1260  } else if (endTime < 0) {
1262  } else if (endTime < beginTime) {
1263  writeError(TLF("Could not build Vaporizer with ID '%' in netedit; begin is greater than end.", edge->getID()));
1264  } else {
1265  // build vaporizer
1266  GNEAdditional* vaporizer = new GNEVaporizer(myNet, edge, beginTime, endTime, name, parameters);
1267  // add it depending of allow undoRed
1268  if (myAllowUndoRedo) {
1269  myNet->getViewNet()->getUndoList()->begin(vaporizer, TL("add vaporizer in '") + edge->getID() + "'");
1271  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(vaporizer, true), true);
1272  myNet->getViewNet()->getUndoList()->end();
1273  // center after creation
1274  if (neteditParameters.centerAfterCreation) {
1275  myNet->getViewNet()->centerTo(vaporizer->getPositionInView(), false);
1276  }
1277  } else {
1279  edge->addChildElement(vaporizer);
1280  vaporizer->incRef("buildVaporizer");
1281  }
1282  }
1283  } else {
1285  }
1286 }
1287 
1288 
1289 void
1290 GNEAdditionalHandler::buildTAZ(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const PositionVector& shape,
1291  const Position& center, const bool fill, const RGBColor& color, const std::vector<std::string>& edgeIDs,
1292  const std::string& name, const Parameterised::Map& parameters) {
1293  // parse edges
1294  const std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_TAZ, edgeIDs);
1295  // check TAZShape
1296  PositionVector TAZShape = shape;
1297  if (TAZShape.size() == 0) {
1298  // declare boundary
1299  Boundary TAZBoundary;
1300  for (const auto& edge : edges) {
1301  TAZBoundary.add(edge->getCenteringBoundary());
1302  }
1303  // iterate over children and add sourceSinkEdge boundaries to make a taz shape
1304  for (const auto& sourceSink : sumoBaseObject->getSumoBaseObjectChildren()) {
1305  // check that childre is a source or sink elements (to avoid parameters)
1306  if ((sourceSink->getTag() == SUMO_TAG_TAZSOURCE) || (sourceSink->getTag() == SUMO_TAG_TAZSINK)) {
1307  const GNEEdge* sourceSinkEdge = myNet->getAttributeCarriers()->retrieveEdge(sourceSink->getStringAttribute(SUMO_ATTR_ID), false);
1308  if (sourceSinkEdge) {
1309  TAZBoundary.add(sourceSinkEdge->getCenteringBoundary());
1310  }
1311  }
1312  }
1313  // update TAZShape
1314  TAZShape = TAZBoundary.getShape(true);
1315  }
1316  // check TAZ
1319  } else if (!checkDuplicatedID(NamespaceIDs::polygons, id)) {
1321  } else if (TAZShape.size() == 0) {
1322  writeError(TLF("Could not build TAZ with ID '%' in netedit; Invalid Shape.", id));
1323  } else {
1324  // get netedit parameters
1325  NeteditParameters neteditParameters(sumoBaseObject);
1326  // build TAZ with the given shape
1327  const Position center2 = center == Position::INVALID ? TAZShape.getCentroid() : center;
1328  GNEAdditional* TAZ = new GNETAZ(id, myNet, TAZShape, center2, fill, color, name, parameters);
1329  // disable updating geometry of TAZ children during insertion (because in large nets provokes slowdowns)
1331  // add it depending of allow undoRed
1332  if (myAllowUndoRedo) {
1333  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ '") + id + "'");
1335  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZ, true), true);
1336  // create TAZEdges
1337  for (const auto& edge : edges) {
1338  // create TAZ Source using GNEChange_Additional
1339  GNEAdditional* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
1340  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSource, true), true);
1341  // create TAZ Sink using GNEChange_Additional
1342  GNEAdditional* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
1343  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSink, true), true);
1344  }
1345  myNet->getViewNet()->getUndoList()->end();
1346  } else {
1348  TAZ->incRef("buildTAZ");
1349  for (const auto& edge : edges) {
1350  // create TAZ Source
1351  GNEAdditional* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
1352  TAZSource->incRef("buildTAZ");
1353  TAZ->addChildElement(TAZSource);
1354  // create TAZ Sink
1355  GNEAdditional* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
1356  TAZSink->incRef("buildTAZ");
1357  TAZ->addChildElement(TAZSink);
1358  }
1359  }
1360  // enable updating geometry again and update geometry of TAZ
1362  // update TAZ parent
1363  TAZ->updateGeometry();
1364  }
1365 }
1366 
1367 
1368 void
1369 GNEAdditionalHandler::buildTAZSource(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const double departWeight) {
1370  // get TAZ parent
1371  GNEAdditional* TAZ = getAdditionalParent(sumoBaseObject, SUMO_TAG_TAZ);
1372  // get edge
1373  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1374  // declare TAZ Sink
1375  GNEAdditional* TAZSink = nullptr;
1376  // check parents
1377  if (TAZ == nullptr) {
1379  } else if (edge == nullptr) {
1381  } else {
1382  // first check if a TAZSink in the same edge for the same TAZ
1383  for (const auto& TAZElement : TAZ->getChildAdditionals()) {
1384  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSINK) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
1385  TAZSink = TAZElement;
1386  }
1387  }
1388  // check if TAZSink has to be created
1389  if (TAZSink == nullptr) {
1390  // Create TAZ with weight 0 (default)
1391  TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 0);
1392  // add it depending of allow undoRed
1393  if (myAllowUndoRedo) {
1394  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Sink in '") + TAZ->getID() + "'");
1396  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSink, true), true);
1397  myNet->getViewNet()->getUndoList()->end();
1398  } else {
1400  TAZSink->incRef("buildTAZSource");
1401  }
1402  }
1403  // now check check if TAZSource exist
1404  GNEAdditional* TAZSource = nullptr;
1405  // first check if a TAZSink in the same edge for the same TAZ
1406  for (const auto& TAZElement : TAZ->getChildAdditionals()) {
1407  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
1408  TAZSource = TAZElement;
1409  }
1410  }
1411  // check if TAZSource has to be created
1412  if (TAZSource == nullptr) {
1413  // Create TAZ only with departWeight
1414  TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, departWeight);
1415  // add it depending of allow undoRed
1416  if (myAllowUndoRedo) {
1417  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Source in '") + TAZ->getID() + "'");
1419  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSource, true), true);
1420  myNet->getViewNet()->getUndoList()->end();
1421  } else {
1423  TAZSource->incRef("buildTAZSource");
1424  }
1425  } else {
1426  // update TAZ Attribute depending of allow undoRed
1427  if (myAllowUndoRedo) {
1428  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("update TAZ Source in '") + TAZ->getID() + "'");
1429  TAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), myNet->getViewNet()->getUndoList());
1430  myNet->getViewNet()->getUndoList()->end();
1431  } else {
1432  TAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), nullptr);
1433  TAZSource->incRef("buildTAZSource");
1434  }
1435  }
1436  }
1437 }
1438 
1439 
1440 void
1441 GNEAdditionalHandler::buildTAZSink(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const double arrivalWeight) {
1442  // get TAZ parent
1443  GNEAdditional* TAZ = getAdditionalParent(sumoBaseObject, SUMO_TAG_TAZ);
1444  // get edge
1445  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1446  // check parents
1447  if (TAZ == nullptr) {
1449  } else if (edge == nullptr) {
1451  } else {
1452  // declare TAZ source
1453  GNEAdditional* TAZSource = nullptr;
1454  // first check if a TAZSink in the same edge for the same TAZ
1455  for (const auto& TAZElement : TAZ->getChildAdditionals()) {
1456  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
1457  TAZSource = TAZElement;
1458  }
1459  }
1460  // check if TAZSource has to be created
1461  if (TAZSource == nullptr) {
1462  // Create TAZ with empty value
1463  TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 0);
1464  // add it depending of allow undoRed
1465  if (myAllowUndoRedo) {
1466  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Source in '") + TAZ->getID() + "'");
1468  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSource, true), true);
1469  myNet->getViewNet()->getUndoList()->end();
1470  } else {
1472  TAZSource->incRef("buildTAZSink");
1473  }
1474  }
1475  GNEAdditional* TAZSink = nullptr;
1476  // first check if a TAZSink in the same edge for the same TAZ
1477  for (const auto& TAZElement : TAZ->getChildAdditionals()) {
1478  if ((TAZElement->getTagProperty().getTag() == SUMO_TAG_TAZSINK) && (TAZElement->getAttribute(SUMO_ATTR_EDGE) == edge->getID())) {
1479  TAZSink = TAZElement;
1480  }
1481  }
1482  // check if TAZSink has to be created
1483  if (TAZSink == nullptr) {
1484  // Create TAZ only with arrivalWeight
1485  TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, arrivalWeight);
1486  // add it depending of allow undoRed
1487  if (myAllowUndoRedo) {
1488  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Sink in '") + TAZ->getID() + "'");
1490  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZSink, true), true);
1491  myNet->getViewNet()->getUndoList()->end();
1492  } else {
1494  TAZSink->incRef("buildTAZSink");
1495  }
1496  } else {
1497  // update TAZ Attribute depending of allow undoRed
1498  if (myAllowUndoRedo) {
1499  myNet->getViewNet()->getUndoList()->begin(TAZ, TL("update TAZ Sink in '") + TAZ->getID() + "'");
1500  TAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), myNet->getViewNet()->getUndoList());
1501  myNet->getViewNet()->getUndoList()->end();
1502  } else {
1503  TAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), nullptr);
1504  TAZSink->incRef("buildTAZSink");
1505  }
1506  }
1507  }
1508 }
1509 
1510 
1511 void
1512 GNEAdditionalHandler::buildTractionSubstation(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const Position& pos,
1513  const double voltage, const double currentLimit, const Parameterised::Map& parameters) {
1514  // check conditions
1517  } else if (voltage < 0) {
1519  } else if (currentLimit < 0) {
1521  } else if (checkDuplicatedID({SUMO_TAG_TRACTION_SUBSTATION}, id)) {
1522  // get netedit parameters
1523  NeteditParameters neteditParameters(sumoBaseObject);
1524  // build traction substation
1525  GNEAdditional* tractionSubstation = new GNETractionSubstation(id, myNet, pos, voltage, currentLimit, parameters);
1526  // insert depending of allowUndoRedo
1527  if (myAllowUndoRedo) {
1528  myNet->getViewNet()->getUndoList()->begin(tractionSubstation, TL("add traction substation '") + id + "'");
1530  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(tractionSubstation, true), true);
1531  myNet->getViewNet()->getUndoList()->end();
1532  } else {
1533  myNet->getAttributeCarriers()->insertAdditional(tractionSubstation);
1534  tractionSubstation->incRef("buildTractionSubstation");
1535  }
1536  } else {
1538  }
1539 }
1540 
1541 
1542 void
1543 GNEAdditionalHandler::buildOverheadWire(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& substationId,
1544  const std::vector<std::string>& laneIDs, const double startPos, const double endPos, const bool friendlyPos,
1545  const std::vector<std::string>& forbiddenInnerLanes, const Parameterised::Map& parameters) {
1546  // check conditions
1550  // get netedit parameters
1551  NeteditParameters neteditParameters(sumoBaseObject);
1552  // get lanes
1553  const auto lanes = parseLanes(SUMO_TAG_OVERHEAD_WIRE_SECTION, laneIDs);
1554  // get traction substation
1555  const auto tractionSubstation = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRACTION_SUBSTATION, substationId, false);
1556  // check lanes
1557  if (lanes.size() > 0) {
1558  // calculate path
1559  if (!GNEAdditional::areLaneConsecutives(lanes)) {
1560  writeError(TLF("Could not build overhead wire with ID '%' in netedit; Lanes aren't consecutives.", id));
1561  } else if (!checkMultiLanePosition(
1562  startPos, lanes.front()->getParentEdge()->getNBEdge()->getFinalLength(),
1563  endPos, lanes.back()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
1565  } else if (tractionSubstation == nullptr) {
1567  } else {
1568  // build Overhead Wire
1569  GNEAdditional* overheadWire = new GNEOverheadWire(id, lanes, tractionSubstation, myNet, startPos, endPos, friendlyPos, forbiddenInnerLanes, parameters);
1570  // insert depending of allowUndoRedo
1571  if (myAllowUndoRedo) {
1572  myNet->getViewNet()->getUndoList()->begin(overheadWire, TL("add overhead wire '") + id + "'");
1574  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(overheadWire, true), true);
1575  myNet->getViewNet()->getUndoList()->end();
1576  } else {
1577  myNet->getAttributeCarriers()->insertAdditional(overheadWire);
1578  for (const auto& lane : lanes) {
1579  lane->addChildElement(overheadWire);
1580  }
1581  overheadWire->incRef("buildOverheadWire");
1582  }
1583  }
1584  } else {
1586  }
1587  } else {
1589  }
1590 }
1591 
1592 
1593 void
1594 GNEAdditionalHandler::buildOverheadWireClamp(const CommonXMLStructure::SumoBaseObject* /* sumoBaseObject */, const std::string& /* id */, const std::string& /* overheadWireIDStartClamp */,
1595  const std::string& /* laneIDStartClamp */, const std::string& /* overheadWireIDEndClamp */, const std::string& /* laneIDEndClamp */,
1596  const Parameterised::Map& /* parameters */) {
1597  //
1598 }
1599 
1600 
1601 void
1602 GNEAdditionalHandler::buildPolygon(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& type,
1603  const RGBColor& color, double layer, double angle, const std::string& imgFile, bool relativePath, const PositionVector& shape, bool geo, bool fill,
1604  double lineWidth, const std::string& name, const Parameterised::Map& parameters) {
1605  // check conditions
1606  if (type == "jupedsim.walkable_area") {
1607  buildJpsWalkableArea(sumoBaseObject, id, shape, geo, name, parameters);
1608  } else if (type == "jupedsim.obstacle") {
1609  buildJpsObstacle(sumoBaseObject, id, shape, geo, name, parameters);
1610  } else if (!SUMOXMLDefinitions::isValidAdditionalID(id)) {
1612  } else if (!checkDuplicatedID(NamespaceIDs::polygons, id)) {
1614  } else if (lineWidth < 0) {
1616  } else {
1617  // get netedit parameters
1618  NeteditParameters neteditParameters(sumoBaseObject);
1619  // create poly
1620  GNEPoly* poly = new GNEPoly(myNet, id, type, shape, geo, fill, lineWidth, color, layer, angle, imgFile, relativePath, name, parameters);
1621  // add it depending of allow undoRed
1622  if (myAllowUndoRedo) {
1623  myNet->getViewNet()->getUndoList()->begin(poly, TL("add polygon '") + id + "'");
1625  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(poly, true), true);
1626  myNet->getViewNet()->getUndoList()->end();
1627  } else {
1628  // insert shape without allowing undo/redo
1630  poly->incRef("addPolygon");
1631  }
1632  }
1633 }
1634 
1635 
1636 void
1637 GNEAdditionalHandler::buildPOI(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& type,
1638  const RGBColor& color, const double x, const double y, const std::string& icon, double layer, double angle,
1639  const std::string& imgFile, bool relativePath, double width, double height, const std::string& name,
1640  const Parameterised::Map& parameters) {
1641  // check conditions
1644  } else if (width < 0) {
1646  } else if (height < 0) {
1648  } else if (!SUMOXMLDefinitions::isValidFilename(imgFile)) {
1650  } else if (checkDuplicatedID(NamespaceIDs::POIs, id)) {
1651  // get netedit parameters
1652  NeteditParameters neteditParameters(sumoBaseObject);
1653  // create POI
1654  GNEPOI* POI = new GNEPOI(myNet, id, type, color, x, y, false, icon, layer, angle, imgFile, relativePath, width, height, name, parameters);
1655  // add it depending of allow undoRed
1656  if (myAllowUndoRedo) {
1657  myNet->getViewNet()->getUndoList()->begin(POI, TL("add POI '") + id + "'");
1659  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POI, true), true);
1660  myNet->getViewNet()->getUndoList()->end();
1661  } else {
1662  // insert shape without allowing undo/redo
1664  POI->incRef("addPOI");
1665  }
1666  } else {
1668  }
1669 }
1670 
1671 
1672 void
1673 GNEAdditionalHandler::buildPOILane(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& type,
1674  const RGBColor& color, const std::string& laneID, double posOverLane, const bool friendlyPos, double posLat,
1675  const std::string& icon, double layer, double angle, const std::string& imgFile, bool relativePath, double width,
1676  double height, const std::string& name, const Parameterised::Map& parameters) {
1677  // check conditions
1680  } else if (width < 0) {
1682  } else if (height < 0) {
1684  } else if (!SUMOXMLDefinitions::isValidFilename(imgFile)) {
1686  } else if (checkDuplicatedID(NamespaceIDs::POIs, id)) {
1687  // get netedit parameters
1688  NeteditParameters neteditParameters(sumoBaseObject);
1689  // get lane
1690  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
1691  // check lane
1692  if (lane == nullptr) {
1694  } else if (!checkLanePosition(posOverLane, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
1696  } else {
1697  // create POI (use GNEAdditional instead GNEPOI for add child references)
1698  GNEAdditional* POILane = new GNEPOI(myNet, id, type, color, lane, posOverLane, friendlyPos, posLat, icon, layer,
1699  angle, imgFile, relativePath, width, height, name, parameters);
1700  // add it depending of allow undoRed
1701  if (myAllowUndoRedo) {
1702  myNet->getViewNet()->getUndoList()->begin(POILane, TL("add POI '") + id + "'");
1704  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POILane, true), true);
1705  myNet->getViewNet()->getUndoList()->end();
1706  } else {
1707  // insert shape without allowing undo/redo
1709  lane->addChildElement(POILane);
1710  POILane->incRef("buildPOILane");
1711  }
1712  }
1713  } else {
1715  }
1716 }
1717 
1718 
1719 void
1720 GNEAdditionalHandler::buildPOIGeo(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& type,
1721  const RGBColor& color, const double lon, const double lat, const std::string& icon, double layer,
1722  double angle, const std::string& imgFile, bool relativePath, double width, double height,
1723  const std::string& name, const Parameterised::Map& parameters) {
1724  // check conditions
1727  } else if (width < 0) {
1729  } else if (height < 0) {
1731  } else if (!SUMOXMLDefinitions::isValidFilename(imgFile)) {
1733  } else if (GeoConvHelper::getFinal().getProjString() == "!") {
1734  writeError(TLF("Could not build POI with ID '%' in netedit", id) + std::string("; ") + TL("Network requires a geo projection."));
1735  } else if (checkDuplicatedID(NamespaceIDs::POIs, id)) {
1736  // get netedit parameters
1737  NeteditParameters neteditParameters(sumoBaseObject);
1738  // create POIGEO
1739  GNEPOI* POIGEO = new GNEPOI(myNet, id, type, color, lon, lat, true, icon, layer, angle, imgFile, relativePath, width, height, name, parameters);
1740  // add it depending of allow undoRed
1741  if (myAllowUndoRedo) {
1742  myNet->getViewNet()->getUndoList()->begin(POIGEO, TL("add POI '") + id + "'");
1744  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POIGEO, true), true);
1745  myNet->getViewNet()->getUndoList()->end();
1746  } else {
1747  // insert shape without allowing undo/redo
1749  POIGEO->incRef("buildPOIGeo");
1750  }
1751  } else {
1753  }
1754 }
1755 
1756 
1757 void
1758 GNEAdditionalHandler::buildJpsWalkableArea(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const PositionVector& shape,
1759  bool geo, const std::string& name, const Parameterised::Map& parameters) {
1760  // check conditions
1763  } else if (!checkDuplicatedID(NamespaceIDs::polygons, id)) {
1765  } else {
1766  // get netedit parameters
1767  NeteditParameters neteditParameters(sumoBaseObject);
1768  // create walkable area
1769  GNEPoly* walkableArea = new GNEPoly(GNE_TAG_JPS_WALKABLEAREA, myNet, id, shape, geo, name, parameters);
1770  // add it depending of allow undoRed
1771  if (myAllowUndoRedo) {
1772  myNet->getViewNet()->getUndoList()->begin(walkableArea, TL("add jps walkable area '") + id + "'");
1774  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(walkableArea, true), true);
1775  myNet->getViewNet()->getUndoList()->end();
1776  } else {
1777  // insert shape without allowing undo/redo
1778  myNet->getAttributeCarriers()->insertAdditional(walkableArea);
1779  walkableArea->incRef("addWalkableArea");
1780  }
1781  }
1782 }
1783 
1784 
1785 void
1786 GNEAdditionalHandler::buildJpsObstacle(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const PositionVector& shape,
1787  bool geo, const std::string& name, const Parameterised::Map& parameters) {
1788  // check conditions
1791  } else if (!checkDuplicatedID(NamespaceIDs::polygons, id)) {
1793  } else {
1794  // get netedit parameters
1795  NeteditParameters neteditParameters(sumoBaseObject);
1796  // create walkable area
1797  GNEPoly* obstacle = new GNEPoly(GNE_TAG_JPS_OBSTACLE, myNet, id, shape, geo, name, parameters);
1798  // add it depending of allow undoRed
1799  if (myAllowUndoRedo) {
1800  myNet->getViewNet()->getUndoList()->begin(obstacle, TL("add jps obstacle '") + id + "'");
1802  myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(obstacle, true), true);
1803  myNet->getViewNet()->getUndoList()->end();
1804  } else {
1805  // insert shape without allowing undo/redo
1807  obstacle->incRef("addObstacle");
1808  }
1809  }
1810 }
1811 
1812 
1813 bool
1815  // check if exist another access for the same busStop in the given edge
1816  for (const auto& additional : busStopParent->getChildAdditionals()) {
1817  for (const auto& lane : edge->getLanes()) {
1818  if (additional->getAttribute(SUMO_ATTR_LANE) == lane->getID()) {
1819  return false;
1820  }
1821  }
1822  }
1823  return true;
1824 }
1825 
1826 
1827 bool
1829  // declare a vector to keep sorted rerouter children
1830  std::vector<std::pair<SUMOTime, SUMOTime>> sortedIntervals;
1831  // iterate over child additional
1832  for (const auto& rerouterChild : rerouter->getChildAdditionals()) {
1833  if (!rerouterChild->getTagProperty().isSymbol()) {
1834  sortedIntervals.push_back(std::make_pair((SUMOTime)0., (SUMOTime)0.));
1835  // set begin and end
1836  sortedIntervals.back().first = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_BEGIN));
1837  sortedIntervals.back().second = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_END));
1838  }
1839  }
1840  // add new intervals
1841  sortedIntervals.push_back(std::make_pair(newBegin, newEnd));
1842  // sort children
1843  std::sort(sortedIntervals.begin(), sortedIntervals.end());
1844  // check overlapping after sorting
1845  for (int i = 0; i < (int)sortedIntervals.size() - 1; i++) {
1846  if (sortedIntervals.at(i).second > sortedIntervals.at(i + 1).first) {
1847  return false;
1848  }
1849  }
1850  return true;
1851 }
1852 
1853 
1854 bool
1855 GNEAdditionalHandler::checkLanePosition(double pos, const double length, const double laneLength, const bool friendlyPos) {
1856  if (friendlyPos) {
1857  return true;
1858  }
1859  // adjust from and to (negative means that start at the end of lane and count backward)
1860  if (pos < 0) {
1861  pos += laneLength;
1862  }
1863  // check extremes
1864  if ((pos < 0) || (pos > laneLength)) {
1865  return false;
1866  }
1867  // check pos + length
1868  if ((pos + length) > laneLength) {
1869  return false;
1870  }
1871  // all OK
1872  return true;
1873 }
1874 
1875 
1876 void
1877 GNEAdditionalHandler::fixLanePosition(double& pos, double& length, const double laneLength) {
1878  // negative pos means that start at the end of lane and count backward)
1879  if (pos < 0) {
1880  pos += laneLength;
1881  }
1882  // set position at the start
1883  if (pos < 0) {
1884  pos = 0;
1885  }
1886  // adjust pos
1887  if (pos >= laneLength) {
1888  pos = (laneLength - POSITION_EPS);
1889  }
1890  // adjust length
1891  if ((length < 0) || ((pos + length) > laneLength)) {
1892  length = POSITION_EPS;
1893  }
1894 }
1895 
1896 
1897 bool
1898 GNEAdditionalHandler::checkLaneDoublePosition(double from, double to, const double laneLength, const bool friendlyPos) {
1899  if (friendlyPos) {
1900  return true;
1901  }
1902  // adjust from and to (negative means that start at the end of lane and count backward)
1903  if (from == INVALID_DOUBLE) {
1904  from = 0;
1905  }
1906  if (to == INVALID_DOUBLE) {
1907  to = laneLength;
1908  }
1909  if (from < 0) {
1910  from += laneLength;
1911  }
1912  if (to < 0) {
1913  to += laneLength;
1914  }
1915  if ((to - from) < POSITION_EPS) {
1916  return false;
1917  }
1918  if ((from < 0) || (from > laneLength)) {
1919  return false;
1920  }
1921  if ((to < 0) || (to > laneLength)) {
1922  return false;
1923  }
1924  return true;
1925 }
1926 
1927 
1928 void
1929 GNEAdditionalHandler::fixLaneDoublePosition(double& from, double& to, const double laneLength) {
1930  // adjust from (negative means that start at the end of lane and count backward)
1931  if (from == INVALID_DOUBLE) {
1932  from = 0;
1933  }
1934  if (to == INVALID_DOUBLE) {
1935  to = laneLength;
1936  }
1937  if (from < 0) {
1938  from += laneLength;
1939  }
1940  if (from < 0) {
1941  from = 0;
1942  } else if (from > laneLength) {
1943  from = laneLength;
1944  }
1945  // adjust to
1946  if (to < 0) {
1947  to += laneLength;
1948  }
1949  if (to < 0) {
1950  to = 0;
1951  } else if (to > laneLength) {
1952  to = laneLength;
1953  }
1954  // to has more priorty as from, and distance between from and to must be >= POSITION_EPS
1955  if ((to - from) < POSITION_EPS) {
1956  if (to >= POSITION_EPS) {
1957  from = to - POSITION_EPS;
1958  } else {
1959  from = 0;
1960  to = POSITION_EPS;
1961  }
1962  }
1963 }
1964 
1965 
1966 bool
1967 GNEAdditionalHandler::checkMultiLanePosition(double fromPos, const double fromLaneLength, const double toPos, const double tolaneLength, const bool friendlyPos) {
1968  if (friendlyPos) {
1969  return true;
1970  } else {
1971  return (checkLanePosition(fromPos, 0, fromLaneLength, false) && checkLanePosition(toPos, 0, tolaneLength, false));
1972  }
1973 }
1974 
1975 
1976 void
1977 GNEAdditionalHandler::fixMultiLanePosition(double fromPos, const double fromLaneLength, double toPos, const double tolaneLength) {
1978  double length = 0;
1979  fixLanePosition(fromPos, length, fromLaneLength);
1980  fixLanePosition(toPos, length, tolaneLength);
1981 }
1982 
1983 
1984 void
1985 GNEAdditionalHandler::writeInvalidID(const SumoXMLTag tag, const std::string& id) {
1986  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("ID contains invalid characters."));
1987 }
1988 
1989 
1990 void
1992  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("Invalid position over lane."));
1993 }
1994 
1995 
1996 void
1997 GNEAdditionalHandler::writeErrorDuplicated(const SumoXMLTag tag, const std::string& id) {
1998  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("Declared twice."));
1999 }
2000 
2001 
2002 void
2003 GNEAdditionalHandler::writeErrorInvalidParent(const SumoXMLTag tag, const std::string& id, const SumoXMLTag parent, const std::string& parentID) {
2004  std::string first, second;
2005  if (id.size() > 0) {
2006  first = TLF("Could not build % '%' in netedit", toString(tag), id);
2007  } else {
2008  first = TLF("Could not build % in netedit", toString(tag));
2009  }
2010  if (parentID.size() > 0) {
2011  second = TLF("% '%' doesn't exist.", toString(parent), parentID);
2012  } else {
2013  second = TLF("% doesn't exist.", toString(parent));
2014  }
2015  writeError(first + std::string("; ") + second);
2016 }
2017 
2018 
2019 void
2020 GNEAdditionalHandler::writeErrorInvalidNegativeValue(const SumoXMLTag tag, const std::string& id, const SumoXMLAttr attribute) {
2021  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TLF("Attribute % cannot be negative.", toString(attribute)));
2022 }
2023 
2024 
2025 void
2027  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("List of VTypes isn't valid."));
2028 }
2029 
2030 
2031 void
2033  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("Filename is invalid."));
2034 }
2035 
2036 
2037 void
2039  writeError(TLF("Could not build % with ID '%' in netedit", toString(tag), id) + std::string("; ") + TL("List of lanes isn't valid."));
2040 }
2041 
2042 
2043 bool
2044 GNEAdditionalHandler::checkListOfVehicleTypes(const std::vector<std::string>& vTypeIDs) const {
2045  for (const auto& vTypeID : vTypeIDs) {
2046  if (!SUMOXMLDefinitions::isValidTypeID(vTypeID)) {
2047  return false;
2048  }
2049  }
2050  return true;
2051 }
2052 
2053 
2056  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2057  return nullptr;
2058  } else if (!sumoBaseObject->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ID)) {
2059  return nullptr;
2060  } else {
2062  }
2063 }
2064 
2065 
2068  if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
2069  // parent interval doesn't exist
2070  return nullptr;
2071  } else if (sumoBaseObject->getParentSumoBaseObject()->getParentSumoBaseObject() == nullptr) {
2072  // rerouter parent doesn't exist
2073  return nullptr;
2074  } else if (!sumoBaseObject->getParentSumoBaseObject()->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ID) || // rerouter ID
2075  !sumoBaseObject->getParentSumoBaseObject()->hasTimeAttribute(SUMO_ATTR_BEGIN) || // interval begin
2076  !sumoBaseObject->getParentSumoBaseObject()->hasTimeAttribute(SUMO_ATTR_END)) { // interval end
2077  return nullptr;
2078  } else {
2083  }
2084 }
2085 
2086 
2087 std::vector<GNEEdge*>
2088 GNEAdditionalHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
2089  std::vector<GNEEdge*> edges;
2090  for (const auto& edgeID : edgeIDs) {
2091  GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2092  // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2093  if (edge == nullptr) {
2094  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_EDGE)));
2095  edges.clear();
2096  return edges;
2097  } else {
2098  edges.push_back(edge);
2099  }
2100  }
2101  return edges;
2102 }
2103 
2104 
2105 std::vector<GNELane*>
2106 GNEAdditionalHandler::parseLanes(const SumoXMLTag tag, const std::vector<std::string>& laneIDs) {
2107  std::vector<GNELane*> lanes;
2108  for (const auto& laneID : laneIDs) {
2109  GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
2110  // empty lanes aren't allowed. If lane is empty, write error, clear lanes and stop
2111  if (lane == nullptr) {
2112  writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("% doesn't exist.", toString(SUMO_TAG_LANE)));
2113  lanes.clear();
2114  return lanes;
2115  } else {
2116  lanes.push_back(lane);
2117  }
2118  }
2119  return lanes;
2120 }
2121 
2122 
2123 bool
2124 GNEAdditionalHandler::checkDuplicatedID(const std::vector<SumoXMLTag> tags, const std::string& id) {
2125  for (const auto& tag : tags) {
2126  // retrieve additional
2127  auto additional = myNet->getAttributeCarriers()->retrieveAdditional(tag, id, false);
2128  // if additional exist, check if overwrite (delete)
2129  if (additional) {
2130  if (!myAllowUndoRedo) {
2131  // only overwrite if allow undo-redo
2132  return false;
2133  } else if (myOverwrite) {
2134  // update additional to overwrite
2135  myAdditionalToOverwrite = additional;
2136  } else {
2137  // duplicated additional
2138  return false;
2139  }
2140  } else {
2141 
2142  }
2143  }
2144  // ID is ok
2145  return true;
2146 }
2147 
2148 
2149 void
2152  // remove element
2154  // reset pointer
2155  myAdditionalToOverwrite = nullptr;
2156  }
2157 }
2158 
2159 
2161  myNet(nullptr),
2162  myAllowUndoRedo(false),
2163  myOverwrite(false) {
2164 }
2165 
2166 // ===========================================================================
2167 // GNEAdditionalHandler::NeteditParameters method definitions
2168 // ===========================================================================
2169 
2171  select(sumoBaseObject->hasBoolAttribute(GNE_ATTR_SELECTED) ? sumoBaseObject->getBoolAttribute(GNE_ATTR_SELECTED) : false),
2172  centerAfterCreation(sumoBaseObject->hasBoolAttribute(GNE_ATTR_CENTER_AFTER_CREATION) ? sumoBaseObject->getBoolAttribute(GNE_ATTR_CENTER_AFTER_CREATION) : false) {
2173 }
2174 
2175 
2177 
2178 
2180  select(false),
2181  centerAfterCreation(false) {
2182 }
2183 
2184 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const std::string DEFAULT_VTYPE_ID
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TRACTION_SUBSTATION
A traction substation.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_CLOSING_REROUTE
reroute of type closing
@ SUMO_TAG_REROUTER
A rerouter.
@ GNE_TAG_MULTI_LANE_AREA_DETECTOR
an e2 detector over multiple lanes (placed here due create Additional Frame)
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_PARKING_AREA_REROUTE
entry for an alternative parking zone
@ SUMO_TAG_TAZSINK
a sink within a district (connection road)
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_STEP
trigger: a step description
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_ROUTE_PROB_REROUTE
probability of route of a reroute
@ GNE_TAG_CALIBRATOR_LANE
A calibrator placed over lane.
@ SUMO_TAG_DET_ENTRY
an e3 entry point
@ SUMO_TAG_PARKING_SPACE
A parking space for a single vehicle within a parking area.
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_OVERHEAD_WIRE_SECTION
An overhead wire section.
@ SUMO_TAG_SINK
Sink(s) specification.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_SOURCE
a source
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_INSTANT_INDUCTION_LOOP
An instantenous induction loop.
@ SUMO_TAG_DEST_PROB_REROUTE
probability of destination of a reroute
@ GNE_TAG_JPS_OBSTACLE
polygon used for draw juPedSim obstacles
@ SUMO_TAG_DET_EXIT
an e3 exit point
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_LANE_AREA_DETECTOR
alternative tag for e2 detector
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ SUMO_TAG_CLOSING_LANE_REROUTE
lane of a reroute of type closing
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
@ GNE_TAG_JPS_WALKABLEAREA
polygon used for draw juPedSim walkable areas
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_ENTRY_EXIT_DETECTOR
alternative tag for e3 detector
@ SUMO_TAG_VSS
A variable speed sign.
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_LANE
@ GNE_ATTR_CENTER_AFTER_CREATION
flag to center camera after element creation
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_PARKING_LENGTH
@ SUMO_ATTR_VOLTAGE
voltage of the traction substation [V]
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_LINEWIDTH
@ SUMO_ATTR_HALTING_TIME_THRESHOLD
@ SUMO_ATTR_WEIGHT
@ SUMO_ATTR_CONTAINER_CAPACITY
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_HALTING_SPEED_THRESHOLD
@ SUMO_ATTR_HEIGHT
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ROADSIDE_CAPACITY
@ SUMO_ATTR_CURRENTLIMIT
current limit of the traction substation [A]
@ SUMO_ATTR_CHARGINGPOWER
@ SUMO_ATTR_PROB
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_CHARGEDELAY
Delay in the charge of charging stations (different of waiting time)
const double INVALID_DOUBLE
invalid double
Definition: StdDefs.h:64
const double SUMO_const_laneWidth
Definition: StdDefs.h:48
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void writeError(const std::string &error)
write error and enable error creating element
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
PositionVector getShape(const bool closeShape) const
get position vector (shape) based on this boundary
Definition: Boundary.cpp:423
SUMOTime getTimeAttribute(const SumoXMLAttr attr) const
get time attribute
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
SumoBaseObject * getParentSumoBaseObject() const
get pointer to mySumoBaseObjectParent SumoBaseObject (if is null, then is the root)
bool hasTimeAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given time attribute
SumoXMLTag getTag() const
get XML myTag
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
const std::vector< SumoBaseObject * > & getSumoBaseObjectChildren() const
get SumoBaseObject children
void buildPolygon(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &type, const RGBColor &color, const double layer, const double angle, const std::string &imgFile, const bool relativePath, const PositionVector &shape, const bool geo, const bool fill, const double lineWidth, const std::string &name, const Parameterised::Map &parameters)
Builds a polygon using the given values.
void buildVariableSpeedSign(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const Position &pos, const std::vector< std::string > &laneIDs, const std::string &name, const std::vector< std::string > &vTypes, const Parameterised::Map &parameters)
Builds a VariableSpeedSign (lane speed additional)
void buildEdgeCalibrator(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &edgeID, const double pos, const std::string &name, const std::string &outfile, const SUMOTime period, const std::string &routeprobe, const double jamThreshold, const std::vector< std::string > &vTypes, const Parameterised::Map &parameters)
builds a microscopic calibrator over an edge
GNEAdditional * getRerouterIntervalParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get rerouter interval parent
void writeInvalidID(const SumoXMLTag tag, const std::string &id)
write invalid id
static void fixLaneDoublePosition(double &from, double &to, const double laneLengt)
fix the given positions over lane
void buildOverheadWire(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &substationId, const std::vector< std::string > &laneIDs, const double startPos, const double endPos, const bool friendlyPos, const std::vector< std::string > &forbiddenInnerLanes, const Parameterised::Map &parameters)
build overhead wire
void buildSingleLaneDetectorE2(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double pos, const double length, const SUMOTime period, const std::string &trafficLight, const std::string &filename, const std::vector< std::string > &vehicleTypes, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a single-lane Area Detector (E2)
void buildPOI(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &type, const RGBColor &color, const double x, const double y, const std::string &icon, const double layer, const double angle, const std::string &imgFile, bool relativePath, const double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI using the given values.
static bool accessCanBeCreated(GNEAdditional *busStopParent, GNEEdge *edge)
check if a GNEAccess can be created in a certain Edge
void buildLaneCalibrator(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double pos, const std::string &name, const std::string &outfile, const SUMOTime period, const std::string &routeprobe, const double jamThreshold, const std::vector< std::string > &vTypes, const Parameterised::Map &parameters)
builds a microscopic calibrator over a lane
void buildTAZSink(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const double arrivalWeight)
Builds a TAZSink (Traffic Assignment Zone)
void buildAccess(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &laneID, const std::string &pos, const double length, const bool friendlyPos, const Parameterised::Map &parameters)
Builds an Access.
void buildVariableSpeedSignStep(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOTime time, const std::string &speed)
Builds a VariableSpeedSign Step.
bool checkDuplicatedID(const std::vector< SumoXMLTag > tags, const std::string &id)
check if given ID correspond to a duplicated additionals
GNEAdditional * getAdditionalParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, SumoXMLTag tag) const
get additional parent
void writeErrorInvalidNegativeValue(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute)
write error "invalid negative element"
void buildTractionSubstation(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const Position &pos, const double voltage, const double currentLimit, const Parameterised::Map &parameters)
build traction substation
std::vector< GNELane * > parseLanes(const SumoXMLTag tag, const std::vector< std::string > &laneIDs)
parse lanes
void writeErrorDuplicated(const SumoXMLTag tag, const std::string &id)
write error "duplicated additional"
void buildRerouterInterval(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOTime begin, const SUMOTime end)
builds a rerouter interval
void buildCalibratorFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameter)
builds a calibrator flow
void buildPOILane(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &type, const RGBColor &color, const std::string &laneID, const double posOverLane, const bool friendlyPos, const double posLat, const std::string &icon, const double layer, const double angle, const std::string &imgFile, const bool relativePath, const double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI over lane using the given values.
void overwriteAdditional()
remove overwritten additional
void buildTAZ(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const PositionVector &shape, const Position &center, const bool fill, const RGBColor &color, const std::vector< std::string > &edgeIDs, const std::string &name, const Parameterised::Map &parameters)
Builds a TAZ (Traffic Assignment Zone)
void buildClosingLaneReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &closedLane, SVCPermissions permissions)
builds a closing lane reroute
void buildParkingSpace(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const double x, const double y, const double z, const std::string &name, const std::string &width, const std::string &length, const std::string &angle, const double slope, const Parameterised::Map &parameters)
Builds a Parking Space.
void writeErrorInvalidVTypes(const SumoXMLTag tag, const std::string &id)
write error "invalid list of vehicle types"
void buildClosingReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &closedEdgeID, SVCPermissions permissions)
builds a closing edge reroute
void writeErrorInvalidPosition(const SumoXMLTag tag, const std::string &id)
write error "invalid position"
static void fixMultiLanePosition(double fromPos, const double fromLaneLength, double toPos, const double tolaneLength)
fix the given positions over two lanes
void buildDestProbReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newEdgeDestinationID, const double probability)
builds a dest prob reroute
void buildDetectorE3(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const Position &pos, const SUMOTime period, const std::string &filename, const std::vector< std::string > &vehicleTypes, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const bool expectedArrival, const Parameterised::Map &parameters)
Builds a multi entry exit detector (E3)
bool checkListOfVehicleTypes(const std::vector< std::string > &vTypeIDs) const
check list of IDs
const bool myAllowUndoRedo
allow undo/redo
static bool checkLaneDoublePosition(double from, const double to, const double laneLength, const bool friendlyPos)
check if the given positions over a lane is valid
void buildJpsObstacle(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const PositionVector &shape, bool geo, const std::string &name, const Parameterised::Map &parameters)
Builds a JuPedSim obstacle using the given values.
void buildParkingAreaReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newParkignAreaID, const double probability, const bool visible)
builds a parking area reroute
static bool checkLanePosition(double pos, const double length, const double laneLength, const bool friendlyPos)
check if the given position over a lane is valid
void buildRouteProbe(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &edgeID, const SUMOTime period, const std::string &name, const std::string &file, const SUMOTime begin, const Parameterised::Map &parameters)
builds a Route probe
void buildBusStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double startPos, const double endPos, const std::string &name, const std::vector< std::string > &lines, const int personCapacity, const double parkingLength, const RGBColor &color, const bool friendlyPosition, const Parameterised::Map &parameters)
Builds a bus stop.
GNEAdditionalHandler()
invalidate default constructo
void writeErrorInvalidFilename(const SumoXMLTag tag, const std::string &id)
write error "invalid filename"
void buildTrainStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double startPos, const double endPos, const std::string &name, const std::vector< std::string > &lines, const int personCapacity, const double parkingLength, const RGBColor &color, const bool friendlyPosition, const Parameterised::Map &parameters)
Builds a train stop.
void buildE1Detector(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double position, const SUMOTime period, const std::string &file, const std::vector< std::string > &vehicleTypes, const std::string &name, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a induction loop detector (E1)
void buildParkingArea(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double startPos, const double endPos, const std::string &departPos, const std::string &name, const std::vector< std::string > &badges, const bool friendlyPosition, const int roadSideCapacity, const bool onRoad, const double width, const double length, const double angle, const bool lefthand, const Parameterised::Map &parameters)
Builds a Parking Area.
void writeErrorInvalidLanes(const SumoXMLTag tag, const std::string &id)
write error "invalid list of lanes"
void buildJpsWalkableArea(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const PositionVector &shape, bool geo, const std::string &name, const Parameterised::Map &parameters)
Builds a JuPedSim walkable area using the given values.
void buildPOIGeo(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &type, const RGBColor &color, const double lon, const double lat, const std::string &icon, const double layer, const double angle, const std::string &imgFile, bool relativePath, const double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI in GEO coordinaten using the given values.
static bool checkOverlappingRerouterIntervals(GNEAdditional *rerouter, const SUMOTime newBegin, const SUMOTime newEnd)
check if an overlapping is produced in rerouter if a interval with certain begin and end is inserted
static void fixLanePosition(double &pos, double &length, const double laneLength)
fix given position over lane
GNENet * myNet
pointer to GNENet
void buildRouteProbReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newRouteID, const double probability)
builds a route prob reroute
void buildDetectorE1Instant(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double pos, const std::string &filename, const std::vector< std::string > &vehicleTypes, const std::string &name, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a Instant Induction Loop Detector (E1Instant)
void buildTAZSource(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const double departWeight)
Builds a TAZSource (Traffic Assignment Zone)
void writeErrorInvalidParent(const SumoXMLTag tag, const std::string &id, const SumoXMLTag parent, const std::string &parentID)
write error "invalid parent element"
void buildChargingStation(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double startPos, const double endPos, const std::string &name, const double chargingPower, const double efficiency, const bool chargeInTransit, const SUMOTime chargeDelay, const std::string &chargeType, const SUMOTime waitingTime, const bool friendlyPosition, const std::string &parkingAreaID, const Parameterised::Map &parameters)
Builds a charging Station.
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::vector< std::string > &edgeIDs)
parse edges
void buildMultiLaneDetectorE2(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::vector< std::string > &lanes, const double pos, const double endPos, const SUMOTime period, const std::string &trafficLight, const std::string &filename, const std::vector< std::string > &vehicleTypes, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a multi-lane Area Detector (E2)
void buildVaporizer(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const SUMOTime from, const SUMOTime endTime, const std::string &name, const Parameterised::Map &parameters)
Builds a vaporizer (lane speed additional)
void buildContainerStop(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &laneID, const double startPos, const double endPos, const std::string &name, const std::vector< std::string > &lines, const int containerCapacity, const double parkingLength, const RGBColor &color, const bool friendlyPosition, const Parameterised::Map &parameters)
Builds a container stop.
GNEAdditional * myAdditionalToOverwrite
additional to overwrite (using undor-redo
void buildRerouter(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const Position &pos, const std::vector< std::string > &edgeIDs, const double prob, const std::string &name, const bool off, const bool optional, const SUMOTime timeThreshold, const std::vector< std::string > &vTypes, const Parameterised::Map &parameters)
builds a rerouter
void buildDetectorEntry(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &laneID, const double pos, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a entry detector (E3)
void buildDetectorExit(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &laneID, const double pos, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a exit detector (E3)
void buildOverheadWireClamp(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::string &overheadWireIDStartClamp, const std::string &laneIDStartClamp, const std::string &overheadWireIDEndClamp, const std::string &laneIDEndClamp, const Parameterised::Map &parameters)
build overhead wire clamp
const bool myOverwrite
check if overwrite
static bool checkMultiLanePosition(double fromPos, const double fromLaneLength, const double toPos, const double tolaneLength, const bool friendlyPos)
check if the given positions over two lanes are valid
An Element which don't belong to GNENet but has influence in the simulation.
Definition: GNEAdditional.h:49
virtual void updateGeometry()=0
update pre-computed geometry information
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform additional changes
static bool areLaneConsecutives(const std::vector< GNELane * > &lanes)
check if the given lanes are consecutive
virtual Position getPositionInView() const =0
Returns position of additional in view.
const std::string getID() const
get ID (all Attribute Carriers have one)
A lane area vehicles can halt at (netedit-version)
Definition: GNEBusStop.h:33
A lane area vehicles can halt at (netedit-version)
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:683
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:1047
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:556
void addChildElement(T *element)
add child element
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
bool allowPedestrians() const
check if current lane allow pedestrians
Definition: GNELane.cpp:202
GNEEdge * getParentEdge() const
get parent edge
Definition: GNELane.cpp:196
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
GNEAdditional * retrieveRerouterInterval(const std::string &rerouterID, const SUMOTime begin, const SUMOTime end) const
Returns the rerouter interval defined by given begin and end.
void insertAdditional(GNEAdditional *additional)
Insert a additional element in container.
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
void deleteAdditional(GNEAdditional *additional, GNEUndoList *undoList)
remove additional
Definition: GNENet.cpp:616
void disableUpdateGeometry()
disable update geometry of elements after inserting or removing an element in net
Definition: GNENet.cpp:2667
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:121
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2022
void enableUpdateGeometry()
Definition: GNENet.cpp:2661
Definition: GNEPOI.h:43
A lane area vehicles can park at (netedit-version)
vehicle space used by GNEParkingAreas
void incRef(const std::string &debugMsg="")
Increase reference.
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:32
Definition: GNETAZ.h:34
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
Representation of a vaporizer in netedit.
Definition: GNEVaporizer.h:33
GNEUndoList * getUndoList() const
get the undoList object
virtual void centerTo(GUIGlID id, bool applyZoom, double zoomDist=20)
centers to the chosen artifact
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:4642
static const std::vector< SumoXMLTag > POIs
POIs namespace.
Definition: NamespaceIDs.h:50
static const std::vector< SumoXMLTag > polygons
polygon namespace
Definition: NamespaceIDs.h:47
C++ TraCI client API implementation.
Definition: POI.h:34
std::map< std::string, std::string > Map
parameters map
Definition: Parameterised.h:45
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:317
A list of positions.
double length2D() const
Returns the length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Structure representing possible vehicle parameter.
std::string vtypeid
The vehicle's type id.
std::string routeid
The vehicle's route id.
static bool isValidTypeID(const std::string &value)
whether the given string is a valid id for an edge or vehicle type
static bool isValidFilename(const std::string &value)
whether the given string is a valid attribute for a filename (for example, a name)
static bool isValidAdditionalID(const std::string &value)
whether the given string is a valid id for an additional object
static bool isValidDetectorID(const std::string &value)
whether the given string is a valid id for an detector
static bool isValidListOfTypeID(const std::string &value)
whether the given string is a valid list of ids for an edge or vehicle type (empty aren't allowed)
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
const bool centerAfterCreation
center view after creation