Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2025 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
24#include <netedit/GNENet.h>
26#include <netedit/GNEUndoList.h>
29
30#include "GNEAccess.h"
32#include "GNEBusStop.h"
33#include "GNECalibrator.h"
34#include "GNECalibratorFlow.h"
35#include "GNEChargingStation.h"
37#include "GNEClosingReroute.h"
38#include "GNEContainerStop.h"
39#include "GNEDestProbReroute.h"
43#include "GNELaneAreaDetector.h"
45#include "GNEOverheadWire.h"
46#include "GNEPOI.h"
47#include "GNEParkingArea.h"
49#include "GNEParkingSpace.h"
50#include "GNEPoly.h"
51#include "GNERerouter.h"
52#include "GNERerouterInterval.h"
53#include "GNERerouterSymbol.h"
54#include "GNERouteProbReroute.h"
55#include "GNERouteProbe.h"
56#include "GNETAZ.h"
58#include "GNEVaporizer.h"
62
63// ===========================================================================
64// GNEAdditionalHandler method definitions
65// ===========================================================================
66
67GNEAdditionalHandler::GNEAdditionalHandler(GNENet* net, const std::string& filename, const bool allowUndoRedo) :
68 AdditionalHandler(filename),
69 myNet(net),
70 myAllowUndoRedo(allowUndoRedo) {
71}
72
73
76
77
78bool
80 // nothing to do
81 return true;
82}
83
84
85bool
86GNEAdditionalHandler::buildBusStop(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,
87 const std::string& laneID, const double startPos, const double endPos, const std::string& name,
88 const std::vector<std::string>& lines, const int personCapacity, const double parkingLength,
89 const RGBColor& color, const bool friendlyPosition, const double angle,
90 const Parameterised::Map& parameters) {
91 // check conditions
92 const auto element = retrieveAdditionalElement(NamespaceIDs::busStops, id);
93 if (!checkElement(SUMO_TAG_BUS_STOP, element)) {
94 return false;
96 return false;
97 } else {
98 // get lane
99 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
100 // check lane
101 if (lane == nullptr) {
103 } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
105 } else if (!checkNegative(SUMO_TAG_BUS_STOP, id, SUMO_ATTR_PERSON_CAPACITY, personCapacity, true)) {
106 return false;
107 } else if (!checkNegative(SUMO_TAG_BUS_STOP, id, SUMO_ATTR_PARKING_LENGTH, parkingLength, true)) {
108 return false;
109 } else {
110 // build busStop
111 GNEAdditional* busStop = GNEBusStop::buildBusStop(id, myNet, myFilename, lane, startPos, endPos, name, lines, personCapacity,
112 parkingLength, color, friendlyPosition, angle, parameters);
113 // insert depending of allowUndoRedo
114 if (myAllowUndoRedo) {
115 myNet->getViewNet()->getUndoList()->begin(busStop, TL("add bus stop '") + id + "'");
116 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(busStop, true), true);
118 } else {
120 lane->addChildElement(busStop);
121 busStop->incRef("buildBusStop");
122 }
123 return true;
124 }
125 }
126}
127
128
129bool
130GNEAdditionalHandler::buildTrainStop(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,
131 const std::string& laneID, const double startPos, const double endPos, const std::string& name,
132 const std::vector<std::string>& lines, const int personCapacity, const double parkingLength,
133 const RGBColor& color, const bool friendlyPosition, const double angle,
134 const Parameterised::Map& parameters) {
135 // check conditions
136 const auto element = retrieveAdditionalElement(NamespaceIDs::busStops, id);
137 if (!checkElement(SUMO_TAG_TRAIN_STOP, element)) {
138 return false;
140 return false;
141 } else {
142 // get lane
143 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
144 // check lane
145 if (lane == nullptr) {
147 } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
149 } else if (!checkNegative(SUMO_TAG_TRAIN_STOP, id, SUMO_ATTR_PERSON_CAPACITY, personCapacity, true)) {
150 return false;
151 } else if (!checkNegative(SUMO_TAG_TRAIN_STOP, id, SUMO_ATTR_PARKING_LENGTH, parkingLength, true)) {
152 return false;
153 } else {
154 // build trainStop
155 GNEAdditional* trainStop = GNEBusStop::buildTrainStop(id, myNet, myFilename, lane, startPos, endPos, name, lines, personCapacity,
156 parkingLength, color, friendlyPosition, angle, parameters);
157 // insert depending of allowUndoRedo
158 if (myAllowUndoRedo) {
159 myNet->getViewNet()->getUndoList()->begin(trainStop, TL("add train stop '") + id + "'");
160 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(trainStop, true), true);
162 } else {
164 lane->addChildElement(trainStop);
165 trainStop->incRef("buildTrainStop");
166 }
167 return true;
168 }
169 }
170}
171
172
173bool
174GNEAdditionalHandler::buildAccess(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID,
175 const std::string& pos, const double length, const bool friendlyPos, const Parameterised::Map& parameters) {
176 // get lane
177 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
178 // get busStop (or trainStop)
179 const auto busStop = getAdditionalParent(sumoBaseObject, SUMO_TAG_BUS_STOP);
180 const auto trainStop = getAdditionalParent(sumoBaseObject, SUMO_TAG_TRAIN_STOP);
181 const auto containerStop = getAdditionalParent(sumoBaseObject, SUMO_TAG_CONTAINER_STOP);
182 // check parent
183 if ((busStop == nullptr) && (trainStop == nullptr) && (containerStop == nullptr)) {
185 }
186 GNEAdditional* accessParent = busStop ? busStop : trainStop ? trainStop : containerStop;
187 // pos double
188 bool validPos = true;
189 double posDouble = 0;
190 if (lane) {
191 if (GNEAttributeCarrier::canParse<double>(pos)) {
192 posDouble = GNEAttributeCarrier::parse<double>(pos);
193 validPos = checkLanePosition(posDouble, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos);
194 } else if (pos == "random" || pos == "doors" || pos == "carriage") {
195 posDouble = INVALID_DOUBLE;
196 } else if (pos.empty()) {
197 posDouble = 0;
198 } else {
199 validPos = false;
200 }
201 }
202 // Check if lane is correct
203 if (lane == nullptr) {
205 } else if (!validPos) {
206 return writeErrorInvalidPosition(SUMO_TAG_ACCESS, accessParent->getID());
207 } else if ((length != -1) && !checkNegative(SUMO_TAG_ACCESS, accessParent->getID(), SUMO_ATTR_LENGTH, length, true)) {
208 return false;
209 } else if (!accessExists(accessParent, lane->getParentEdge())) {
210 return writeError(TLF("Could not build access in netedit; % '%' already owns an access in the edge '%'", accessParent->getTagStr(), accessParent->getID(), lane->getParentEdge()->getID()));
211 } else if (!containerStop && !lane->allowPedestrians()) {
212 // only for busStops and trainStops
213 return writeError(TLF("Could not build access in netedit; The lane '%' doesn't support pedestrians", lane->getID()));
214 } else {
215 // build access
216 GNEAdditional* access = new GNEAccess(accessParent, lane, posDouble, pos, friendlyPos, length, parameters);
217 // insert depending of allowUndoRedo
218 if (myAllowUndoRedo) {
219 myNet->getViewNet()->getUndoList()->begin(access, TL("add access in '") + accessParent->getID() + "'");
220 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(access, true), true);
222 } else {
224 lane->addChildElement(access);
225 accessParent->addChildElement(access);
226 access->incRef("buildAccess");
227 }
228 return true;
229 }
230}
231
232
233bool
234GNEAdditionalHandler::buildContainerStop(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& laneID,
235 const double startPos, const double endPos, const std::string& name, const std::vector<std::string>& lines, const int containerCapacity,
236 const double parkingLength, const RGBColor& color, const bool friendlyPosition, const double angle, const Parameterised::Map& parameters) {
237 // check conditions
238 const auto element = retrieveAdditionalElement({SUMO_TAG_CONTAINER_STOP}, id);
239 if (!checkElement(SUMO_TAG_CONTAINER_STOP, element)) {
240 return false;
242 return false;
243 } else {
244 // get lane
245 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
246 // check lane
247 if (lane == nullptr) {
249 } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
251 } else if (!checkNegative(SUMO_TAG_CONTAINER_STOP, id, SUMO_ATTR_CONTAINER_CAPACITY, containerCapacity, true)) {
252 return false;
253 } else if (!checkNegative(SUMO_TAG_CONTAINER_STOP, id, SUMO_ATTR_PARKING_LENGTH, parkingLength, true)) {
254 return false;
255 } else {
256 // build containerStop
257 GNEAdditional* containerStop = new GNEContainerStop(id, myNet, myFilename, lane, startPos, endPos, name, lines, containerCapacity, parkingLength,
258 color, friendlyPosition, angle, parameters);
259 // insert depending of allowUndoRedo
260 if (myAllowUndoRedo) {
261 myNet->getViewNet()->getUndoList()->begin(containerStop, TL("add container stop '") + id + "'");
262 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(containerStop, true), true);
264 } else {
266 lane->addChildElement(containerStop);
267 containerStop->incRef("buildContainerStop");
268 }
269 return true;
270 }
271 }
272}
273
274
275bool
277 const std::string& laneID, const double startPos, const double endPos, const std::string& name, const double chargingPower,
278 const double efficiency, const bool chargeInTransit, const SUMOTime chargeDelay, const std::string& chargeType,
279 const SUMOTime waitingTime, const bool friendlyPosition, const std::string& parkingAreaID, const Parameterised::Map& parameters) {
280 // check conditions
281 const auto element = retrieveAdditionalElement({SUMO_TAG_CHARGING_STATION}, id);
283 return false;
285 return false;
286 } else {
287 // get lane
288 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
289 // check lane
290 if (lane == nullptr) {
292 } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
294 } else if (!checkNegative(SUMO_TAG_CHARGING_STATION, id, SUMO_ATTR_CHARGINGPOWER, chargingPower, true)) {
295 return false;
296 } else if (!checkNegative(SUMO_TAG_CHARGING_STATION, id, SUMO_ATTR_CHARGEDELAY, chargeDelay, true)) {
297 return false;
298 } else if (!SUMOXMLDefinitions::ChargeTypes.hasString(chargeType)) {
299 return writeError(TLF("Could not build % with ID '%' in netedit; Invalid charge type '%' .", toString(SUMO_TAG_CHARGING_STATION), id, chargeType));
300 } else {
301 // build chargingStation
302 GNEAdditional* chargingStation = new GNEChargingStation(id, myNet, myFilename, lane, startPos, endPos, name, chargingPower, efficiency, chargeInTransit,
303 chargeDelay, chargeType, waitingTime, parkingAreaID, friendlyPosition, parameters);
304 // insert depending of allowUndoRedo
305 if (myAllowUndoRedo) {
306 myNet->getViewNet()->getUndoList()->begin(chargingStation, TL("add charging station '") + id + "'");
307 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(chargingStation, true), true);
309 } else {
310 myNet->getAttributeCarriers()->insertAdditional(chargingStation);
311 lane->addChildElement(chargingStation);
312 chargingStation->incRef("buildChargingStation");
313 }
314 return true;
315 }
316 }
317}
318
319
320bool
321GNEAdditionalHandler::buildParkingArea(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& laneID,
322 const double startPos, const double endPos, const std::string& departPos, const std::string& name,
323 const std::vector<std::string>& badges, const bool friendlyPosition, const int roadSideCapacity, const bool onRoad,
324 const double width, const double length, const double angle, const bool lefthand, const Parameterised::Map& parameters) {
325 // check conditions
326 const auto element = retrieveAdditionalElement({SUMO_TAG_PARKING_AREA}, id);
327 if (!checkElement(SUMO_TAG_PARKING_AREA, element)) {
328 return false;
330 return false;
331 } else {
332 // get lane
333 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
334 // get departPos double
335 const double departPosDouble = GNEAttributeCarrier::canParse<double>(departPos) ? GNEAttributeCarrier::parse<double>(departPos) : 0;
336 // check lane
337 if (lane == nullptr) {
339 } else if (!checkLaneDoublePosition(startPos, endPos, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosition)) {
341 } else if (!checkNegative(SUMO_TAG_PARKING_AREA, id, SUMO_ATTR_ROADSIDE_CAPACITY, roadSideCapacity, true)) {
342 return false;
343 } else if (!checkNegative(SUMO_TAG_PARKING_AREA, id, SUMO_ATTR_WIDTH, width, true)) {
344 return false;
345 } else if (!checkNegative(SUMO_TAG_PARKING_AREA, id, SUMO_ATTR_LENGTH, length, true)) {
346 return false;
347 } else if ((departPosDouble < 0) || (departPosDouble > lane->getParentEdge()->getNBEdge()->getFinalLength())) {
348 return writeError(TLF("Could not build parking area with ID '%' in netedit; Invalid departPos over lane.", id));
349 } else {
350 // build parkingArea
351 GNEAdditional* parkingArea = new GNEParkingArea(id, myNet, myFilename, lane, startPos, endPos, GNEAttributeCarrier::canParse<double>(departPos) ? departPos : "",
352 name, badges, friendlyPosition, roadSideCapacity, onRoad,
353 (width == 0) ? SUMO_const_laneWidth : width, length, angle, lefthand, parameters);
354 // insert depending of allowUndoRedo
355 if (myAllowUndoRedo) {
356 myNet->getViewNet()->getUndoList()->begin(parkingArea, TL("add parking area '") + id + "'");
357 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingArea, true), true);
359 } else {
361 lane->addChildElement(parkingArea);
362 parkingArea->incRef("buildParkingArea");
363 }
364 return true;
365 }
366 }
367}
368
369
370bool
371GNEAdditionalHandler::buildParkingSpace(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const double x, const double y, const double z,
372 const std::string& name, const std::string& width, const std::string& length, const std::string& angle, const double slope,
373 const Parameterised::Map& parameters) {
374 // check width and heights
375 if (!width.empty() && !GNEAttributeCarrier::canParse<double>(width)) {
376 return writeError(TL("Could not build parking space in netedit; attribute width cannot be parse to float."));
377 } else if (!length.empty() && !GNEAttributeCarrier::canParse<double>(length)) {
378 return writeError(TL("Could not build parking space in netedit; attribute length cannot be parse to float."));
379 } else if (!angle.empty() && !GNEAttributeCarrier::canParse<double>(angle)) {
380 return writeError(TL("Could not build parking space in netedit; attribute angle cannot be parse to float."));
381 } else {
382 // get lane
383 GNEAdditional* parkingArea = getAdditionalParent(sumoBaseObject, SUMO_TAG_PARKING_AREA);
384 // get double values
385 const double widthDouble = width.empty() ? INVALID_DOUBLE : GNEAttributeCarrier::parse<double>(width);
386 const double lengthDouble = length.empty() ? INVALID_DOUBLE : GNEAttributeCarrier::parse<double>(length);
387 const double angleDouble = angle.empty() ? INVALID_DOUBLE : GNEAttributeCarrier::parse<double>(angle);
388 // check lane
389 if (parkingArea == nullptr) {
391 } else if ((widthDouble != INVALID_DOUBLE) && !checkNegative(SUMO_TAG_PARKING_SPACE, parkingArea->getID(), SUMO_ATTR_WIDTH, widthDouble, true)) {
392 return false;
393 } else if ((lengthDouble != INVALID_DOUBLE) && !checkNegative(SUMO_TAG_PARKING_SPACE, parkingArea->getID(), SUMO_ATTR_LENGTH, lengthDouble, true)) {
394 return false;
395 } else {
396 // build parkingSpace
397 GNEAdditional* parkingSpace = new GNEParkingSpace(parkingArea, Position(x, y, z), widthDouble, lengthDouble, angleDouble, slope, name, parameters);
398 // insert depending of allowUndoRedo
399 if (myAllowUndoRedo) {
400 myNet->getViewNet()->getUndoList()->begin(parkingSpace, TL("add parking space in '") + parkingArea->getID() + "'");
401 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingSpace, true), true);
403 } else {
405 parkingArea->addChildElement(parkingSpace);
406 parkingSpace->incRef("buildParkingSpace");
407 }
408 // update geometry (due boundaries)
409 parkingSpace->updateGeometry();
410 return true;
411 }
412 }
413}
414
415
416bool
417GNEAdditionalHandler::buildE1Detector(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& laneID,
418 const double position, const SUMOTime period, const std::string& file, const std::vector<std::string>& vehicleTypes,
419 const std::vector<std::string>& nextEdges, const std::string& detectPersons, const std::string& name,
420 const bool friendlyPos, const Parameterised::Map& parameters) {
421 // check conditions
422 const auto element = retrieveAdditionalElement({SUMO_TAG_INDUCTION_LOOP}, id);
423 if (!checkElement(SUMO_TAG_INDUCTION_LOOP, element)) {
424 return false;
426 return false;
427 } else {
428 // get lane
429 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
430 // check lane
431 if (lane == nullptr) {
433 } else if (!checkLanePosition(position, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
435 } else if (!checkNegative(SUMO_TAG_INDUCTION_LOOP, id, SUMO_ATTR_PERIOD, period, true)) {
436 return false;
437 } else if (!checkFileName(SUMO_TAG_INDUCTION_LOOP, id, SUMO_ATTR_FILE, file)) {
438 return false;
439 } else if (!checkListOfVehicleTypes(SUMO_TAG_INDUCTION_LOOP, id, vehicleTypes)) {
440 return false;
441 } else {
442 // build E1
443 GNEAdditional* detectorE1 = new GNEInductionLoopDetector(id, myNet, myFilename, lane, position, period, file, vehicleTypes,
444 nextEdges, detectPersons, name, friendlyPos, parameters);
445 // insert depending of allowUndoRedo
446 if (myAllowUndoRedo) {
447 myNet->getViewNet()->getUndoList()->begin(detectorE1, TL("add induction loop '") + id + "'");
448 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1, true), true);
450 } else {
452 lane->addChildElement(detectorE1);
453 detectorE1->incRef("buildDetectorE1");
454 }
455 return true;
456 }
457 }
458}
459
460
461bool
462GNEAdditionalHandler::buildSingleLaneDetectorE2(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& laneID,
463 const double pos, const double length, const SUMOTime period, const std::string& trafficLight, const std::string& filename,
464 const std::vector<std::string>& vehicleTypes, const std::vector<std::string>& nextEdges, const std::string& detectPersons,
465 const std::string& name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold,
466 const bool friendlyPos, const bool show, const Parameterised::Map& parameters) {
467 // check conditions
470 return false;
472 return false;
473 } else {
474 // get lane
475 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
476 // check lane
477 if (lane == nullptr) {
479 } else {
480 // check friendlyPos in small lanes
481 const bool friendlyPosCheck = checkFriendlyPosSmallLanes(pos, length, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos);
482 if (!checkLanePosition(pos, length, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPosCheck)) {
484 } else if (!checkNegative(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_LENGTH, length, true)) {
485 return false;
486 } else if ((period != -1) && !checkNegative(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_PERIOD, period, true)) {
487 return false;
488 } else if ((trafficLight.size() > 0) && !(SUMOXMLDefinitions::isValidNetID(trafficLight))) {
489 // temporal
490 return writeError(TLF("Could not build lane area detector with ID '%' in netedit; invalid traffic light ID.", id));
491 } else if (!checkNegative(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_HALTING_TIME_THRESHOLD, timeThreshold, true)) {
492 return false;
493 } else if (!checkNegative(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {
494 return false;
495 } else if (!checkNegative(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_JAM_DIST_THRESHOLD, jamThreshold, true)) {
496 return false;
497 } else if (!checkFileName(SUMO_TAG_LANE_AREA_DETECTOR, id, SUMO_ATTR_FILE, filename)) {
498 return false;
499 } else if (!checkListOfVehicleTypes(SUMO_TAG_LANE_AREA_DETECTOR, id, vehicleTypes)) {
500 return false;
501 } else {
502 // build E2 single lane
503 GNEAdditional* detectorE2 = new GNELaneAreaDetector(id, myNet, myFilename, lane, pos, length, period, trafficLight, filename,
504 vehicleTypes, nextEdges, detectPersons, name, timeThreshold,
505 speedThreshold, jamThreshold, friendlyPosCheck, show, parameters);
506 // insert depending of allowUndoRedo
507 if (myAllowUndoRedo) {
508 myNet->getViewNet()->getUndoList()->begin(detectorE2, TL("add lane area detector '") + id + "'");
509 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
511 } else {
513 lane->addChildElement(detectorE2);
514 detectorE2->incRef("buildDetectorE2");
515 }
516 return true;
517 }
518 }
519 }
520}
521
522
523bool
524GNEAdditionalHandler::buildMultiLaneDetectorE2(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::vector<std::string>& laneIDs,
525 const double pos, const double endPos, const SUMOTime period, const std::string& trafficLight, const std::string& filename,
526 const std::vector<std::string>& vehicleTypes, const std::vector<std::string>& nextEdges, const std::string& detectPersons,
527 const std::string& name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold,
528 const bool friendlyPos, const bool show, const Parameterised::Map& parameters) {
529 // check conditions
532 return false;
534 return false;
535 } else {
536 // get lanes
537 const auto lanes = parseLanes(GNE_TAG_MULTI_LANE_AREA_DETECTOR, id, laneIDs);
538 // check lanes
539 if (lanes.empty()) {
540 return false;
541 } else {
542 // calculate path
544 return writeError(TLF("Could not build lane area detector with ID '%' in netedit; Lanes aren't consecutives.", id));
545 } else if (!checkMultiLanePosition(
546 pos, lanes.front()->getParentEdge()->getNBEdge()->getFinalLength(),
547 endPos, lanes.back()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
549 } else if ((period != -1) && !checkNegative(GNE_TAG_MULTI_LANE_AREA_DETECTOR, id, SUMO_ATTR_PERIOD, period, true)) {
550 return false;
551 } else if ((trafficLight.size() > 0) && !(SUMOXMLDefinitions::isValidNetID(trafficLight))) {
552 // temporal
553 return writeError(TLF("Could not build lane area detector with ID '%' in netedit; invalid traffic light ID.", id));
555 return false;
557 return false;
559 return false;
561 return false;
562 } else if (!checkListOfVehicleTypes(GNE_TAG_MULTI_LANE_AREA_DETECTOR, id, vehicleTypes)) {
563 return false;
564 } else {
565 // build E2 multilane detector
566 GNEAdditional* detectorE2 = new GNELaneAreaDetector(id, myNet, myFilename, lanes, pos, endPos, period, trafficLight, filename,
567 vehicleTypes, nextEdges, detectPersons, name, timeThreshold,
568 speedThreshold, jamThreshold, friendlyPos, show, parameters);
569 // insert depending of allowUndoRedo
570 if (myAllowUndoRedo) {
571 myNet->getViewNet()->getUndoList()->begin(detectorE2, TL("add lane area detector '") + id + "'");
572 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE2, true), true);
574 } else {
576 for (const auto& lane : lanes) {
577 lane->addChildElement(detectorE2);
578 }
579 detectorE2->incRef("buildDetectorE2Multilane");
580 }
581 return true;
582 }
583 }
584 }
585}
586
587
588bool
589GNEAdditionalHandler::buildDetectorE3(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const Position& pos, const SUMOTime period,
590 const std::string& filename, const std::vector<std::string>& vehicleTypes, const std::vector<std::string>& nextEdges,
591 const std::string& detectPersons, const std::string& name, const SUMOTime timeThreshold, const double speedThreshold,
592 const bool openEntry, const bool expectedArrival, const Parameterised::Map& parameters) {
593 // check conditions
596 return false;
598 return false;
599 } else if (!checkNegative(SUMO_TAG_ENTRY_EXIT_DETECTOR, id, SUMO_ATTR_PERIOD, period, true)) {
600 return false;
601 } else if (!checkNegative(SUMO_TAG_ENTRY_EXIT_DETECTOR, id, SUMO_ATTR_HALTING_TIME_THRESHOLD, timeThreshold, true)) {
602 return false;
603 } else if (!checkNegative(SUMO_TAG_ENTRY_EXIT_DETECTOR, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {
604 return false;
605 } else if (!checkFileName(SUMO_TAG_ENTRY_EXIT_DETECTOR, id, SUMO_ATTR_FILE, filename)) {
606 return false;
607 } else if (!checkListOfVehicleTypes(SUMO_TAG_ENTRY_EXIT_DETECTOR, id, vehicleTypes)) {
608 return false;
609 } else {
610 // build E3
611 GNEAdditional* E3 = new GNEMultiEntryExitDetector(id, myNet, myFilename, pos, period, filename, vehicleTypes, nextEdges, detectPersons,
612 name, timeThreshold, speedThreshold, openEntry, expectedArrival, parameters);
613 // insert depending of allowUndoRedo
614 if (myAllowUndoRedo) {
615 myNet->getViewNet()->getUndoList()->begin(E3, TL("add entry-exit detector '") + id + "'");
616 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(E3, true), true);
618 } else {
620 E3->incRef("buildDetectorE3");
621 }
622 return true;
623 }
624}
625
626
627bool
628GNEAdditionalHandler::buildDetectorEntry(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID, const double pos,
629 const bool friendlyPos, const Parameterised::Map& parameters) {
630 // get lane
631 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
632 // get E3 parent
634 // Check if Detector E3 parent and lane is correct
635 if (lane == nullptr) {
637 } else if (E3 == nullptr) {
639 } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
641 } else {
642 // build entry instant
643 GNEAdditional* entry = new GNEEntryExitDetector(SUMO_TAG_DET_ENTRY, E3, lane, pos, friendlyPos, parameters);
644 // insert depending of allowUndoRedo
645 if (myAllowUndoRedo) {
646 myNet->getViewNet()->getUndoList()->begin(entry, TL("add entry detector in '") + E3->getID() + "'");
647 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(entry, true), true);
649 } else {
651 lane->addChildElement(entry);
652 E3->addChildElement(entry);
653 entry->incRef("buildDetectorEntry");
654 }
655 return true;
656 }
657}
658
659
660bool
661GNEAdditionalHandler::buildDetectorExit(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& laneID, const double pos,
662 const bool friendlyPos, const Parameterised::Map& parameters) {
663 // get lane
664 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
665 // get E3 parent
667 // Check if Detector E3 parent and lane is correct
668 if (lane == nullptr) {
670 } else if (E3 == nullptr) {
672 } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
674 } else {
675 // build exit instant
676 GNEAdditional* exit = new GNEEntryExitDetector(SUMO_TAG_DET_EXIT, E3, lane, pos, friendlyPos, parameters);
677 // insert depending of allowUndoRedo
678 if (myAllowUndoRedo) {
679 myNet->getViewNet()->getUndoList()->begin(exit, TL("add exit detector in '") + E3->getID() + "'");
680 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(exit, true), true);
682 } else {
684 lane->addChildElement(exit);
685 E3->addChildElement(exit);
686 exit->incRef("buildDetectorExit");
687 }
688 return true;
689 }
690}
691
692
693bool
694GNEAdditionalHandler::buildDetectorE1Instant(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& laneID, double pos,
695 const std::string& filename, const std::vector<std::string>& vehicleTypes, const std::vector<std::string>& nextEdges,
696 const std::string& detectPersons, const std::string& name, const bool friendlyPos, const Parameterised::Map& parameters) {
697 // check conditions
700 return false;
702 return false;
703 } else {
704 // get lane
705 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
706 // check lane
707 if (lane == nullptr) {
710 return false;
711 } else if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
713 } else {
714 // build E1 instant
715 GNEAdditional* detectorE1Instant = new GNEInstantInductionLoopDetector(id, myNet, myFilename, lane, pos, filename, vehicleTypes, nextEdges,
716 detectPersons, name, friendlyPos, parameters);
717 // insert depending of allowUndoRedo
718 if (myAllowUndoRedo) {
719 myNet->getViewNet()->getUndoList()->begin(detectorE1Instant, TL("add instant induction loop '") + id + "'");
720 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(detectorE1Instant, true), true);
722 } else {
723 myNet->getAttributeCarriers()->insertAdditional(detectorE1Instant);
724 lane->addChildElement(detectorE1Instant);
725 detectorE1Instant->incRef("buildDetectorE1Instant");
726 }
727 return true;
728 }
729 }
730}
731
732
733bool
734GNEAdditionalHandler::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
743 if (!checkElement(GNE_TAG_CALIBRATOR_LANE, element)) {
744 return false;
746 return false;
747 } else if ((routeprobeID.size() > 0) && (routeProbe == nullptr)) {
749 } else if (lane == nullptr) {
751 } else {
752 // check lane
753 if (!checkLanePosition(pos, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), false)) {
755 } else if (!checkNegative(GNE_TAG_CALIBRATOR_LANE, id, SUMO_ATTR_PERIOD, period, true)) {
756 return false;
757 } else if (!checkNegative(GNE_TAG_CALIBRATOR_LANE, id, SUMO_ATTR_JAM_DIST_THRESHOLD, jamThreshold, true)) {
758 return false;
759 } else {
760 // build Calibrator
761 GNEAdditional* calibrator = (routeProbe == nullptr) ?
762 new GNECalibrator(id, myNet, myFilename, lane, pos, period, name, outfile, jamThreshold, vTypes, parameters) :
763 new GNECalibrator(id, myNet, myFilename, lane, pos, period, name, outfile, routeProbe, jamThreshold, vTypes, parameters);
764 // insert depending of allowUndoRedo
765 if (myAllowUndoRedo) {
766 myNet->getViewNet()->getUndoList()->begin(calibrator, TL("add lane calibrator '") + id + "'");
767 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
769 // check if center after creation
772 myNet->getViewNet()->centerTo(calibrator->getPositionInView(), false);
773 }
774 } else {
776 lane->addChildElement(calibrator);
777 if (routeProbe) {
778 routeProbe->addChildElement(calibrator);
779 }
780 calibrator->incRef("buildCalibrator");
781 }
782 return true;
783 }
784 }
785}
786
787
788bool
789GNEAdditionalHandler::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
798 if (!checkElement(SUMO_TAG_CALIBRATOR, element)) {
799 return false;
801 return false;
802 } else if ((routeprobeID.size() > 0) && (routeProbe == nullptr)) {
804 } else if (edge == nullptr) {
806 } else {
807 if (!checkLanePosition(pos, 0, edge->getChildLanes().front()->getParentEdge()->getNBEdge()->getFinalLength(), false)) {
809 } else if (!checkNegative(SUMO_TAG_CALIBRATOR, id, SUMO_ATTR_PERIOD, period, true)) {
810 return false;
811 } else if (!checkNegative(SUMO_TAG_CALIBRATOR, id, SUMO_ATTR_JAM_DIST_THRESHOLD, jamThreshold, true)) {
812 return false;
813 } else {
814 // build Calibrator
815 GNEAdditional* calibrator = (routeProbe == nullptr) ?
816 new GNECalibrator(id, myNet, myFilename, edge, pos, period, name, outfile, jamThreshold, vTypes, parameters) :
817 new GNECalibrator(id, myNet, myFilename, edge, pos, period, name, outfile, routeProbe, jamThreshold, vTypes, parameters);
818 // insert depending of allowUndoRedo
819 if (myAllowUndoRedo) {
820 myNet->getViewNet()->getUndoList()->begin(calibrator, TL("add calibrator '") + id + "'");
821 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(calibrator, true), true);
823 // check if center after creation
826 myNet->getViewNet()->centerTo(calibrator->getPositionInView(), false);
827 }
828 } else {
830 edge->addChildElement(calibrator);
831 if (routeProbe) {
832 routeProbe->addChildElement(calibrator);
833 }
834 calibrator->incRef("buildCalibrator");
835 }
836 return true;
837 }
838 }
839}
840
841
842bool
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) {
852 return writeErrorInvalidParent(SUMO_TAG_FLOW, "", SUMO_TAG_VTYPE, vehicleParameter.vtypeid);
853 } else if (route == nullptr) {
854 return writeErrorInvalidParent(SUMO_TAG_FLOW, "", SUMO_TAG_ROUTE, vehicleParameter.routeid);
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() + "'");
863 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(flow, true), true);
865 } else {
867 calibrator->addChildElement(flow);
868 route->addChildElement(flow);
869 vType->addChildElement(flow);
870 flow->incRef("buildCalibratorFlow");
871 }
872 return true;
873 }
874}
875
876
877bool
878GNEAdditionalHandler::buildRerouter(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const Position& pos,
879 const std::vector<std::string>& edgeIDs, const double prob, const std::string& name,
880 const bool off, const bool optional, const SUMOTime timeThreshold,
881 const std::vector<std::string>& vTypes, const Parameterised::Map& parameters) {
882 // check conditions
883 const auto element = retrieveAdditionalElement({SUMO_TAG_REROUTER}, id);
884 if (!checkElement(SUMO_TAG_REROUTER, element)) {
885 return false;
886 } else if (!checkValidAdditionalID(SUMO_TAG_REROUTER, id)) {
887 return false;
888 } else if (!checkNegative(SUMO_TAG_REROUTER, id, SUMO_ATTR_PROB, prob, true)) {
889 return false;
890 } else if (!checkNegative(SUMO_TAG_REROUTER, id, SUMO_ATTR_HALTING_TIME_THRESHOLD, timeThreshold, true)) {
891 return false;
892 } else if (!checkListOfVehicleTypes(SUMO_TAG_REROUTER, id, vTypes)) {
893 return false;
894 } else {
895 // parse edges
896 std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_REROUTER, id, edgeIDs);
897 // check edges
898 if (edges.empty()) {
899 return false;
900 } else {
901 GNEAdditional* rerouter = nullptr;
902 // continue depending of position
903 if (pos == Position::INVALID) {
904 if (edges.size() > 0) {
905 PositionVector laneShape = edges.front()->getChildLanes().front()->getLaneShape();
906 // move to side
907 laneShape.move2side(3);
908 // create rerouter
909 rerouter = new GNERerouter(id, myNet, myFilename, laneShape.positionAtOffset2D(laneShape.length2D() - 6), name, prob, off, optional, timeThreshold, vTypes, parameters);
910 } else {
911 rerouter = new GNERerouter(id, myNet, myFilename, Position(0, 0), name, prob, off, optional, timeThreshold, vTypes, parameters);
912 }
913 } else {
914 rerouter = new GNERerouter(id, myNet, myFilename, pos, name, prob, off, optional, timeThreshold, vTypes, parameters);
915 }
916 // create rerouter Symbols
917 std::vector<GNEAdditional*> rerouterSymbols;
918 for (const auto& edge : edges) {
919 rerouterSymbols.push_back(new GNERerouterSymbol(rerouter, edge));
920 }
921 // insert depending of allowUndoRedo
922 if (myAllowUndoRedo) {
923 myNet->getViewNet()->getUndoList()->begin(rerouter, TL("add rerouter '") + id + "'");
924 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouter, true), true);
925 // add symbols
926 for (const auto& rerouterSymbol : rerouterSymbols) {
927 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterSymbol, true), true);
928 }
930 } else {
932 rerouter->incRef("buildRerouter");
933 // add symbols into rerouter
934 for (const auto& rerouterSymbol : rerouterSymbols) {
935 rerouter->addChildElement(rerouterSymbol);
936 }
937 // add symbols into edges
938 for (int i = 0; i < (int)edges.size(); i++) {
939 edges.at(i)->addChildElement(rerouterSymbols.at(i));
940 }
941 }
942 return true;
943 }
944 }
945}
946
947
948bool
950 // get rerouter parent
951 GNEAdditional* rerouter = getAdditionalParent(sumoBaseObject, SUMO_TAG_REROUTER);
952 // check if rerouter exist
953 if (rerouter == nullptr) {
955 } else if (!checkNegative(SUMO_TAG_INTERVAL, rerouter->getID(), SUMO_ATTR_BEGIN, begin, true)) {
956 return false;
957 } else if (!checkNegative(SUMO_TAG_INTERVAL, rerouter->getID(), SUMO_ATTR_END, end, true)) {
958 return false;
959 } else if (end < begin) {
960 return writeError(TLF("Could not build interval with ID '%' in netedit; begin is greater than end.", rerouter->getID()));
961 } else {
962 // check if new interval will produce a overlapping
963 if (checkOverlappingRerouterIntervals(rerouter, begin, end)) {
964 // create rerouter interval and add it into rerouter parent
965 GNEAdditional* rerouterInterval = new GNERerouterInterval(rerouter, begin, end);
966 // insert depending of allowUndoRedo
967 if (myAllowUndoRedo) {
968 myNet->getViewNet()->getUndoList()->begin(rerouterInterval, TL("add rerouter interval in '") + rerouter->getID() + "'");
969 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(rerouterInterval, true), true);
971 } else {
972 rerouter->addChildElement(rerouterInterval);
973 rerouterInterval->incRef("buildRerouterInterval");
974 }
975 } else {
976 return writeError(TLF("Could not build interval with begin '%' and end '%' in '%' due overlapping.", toString(begin), toString(end), rerouter->getID()));
977 }
978 // update centering boundary of rerouter parent
979 rerouter->updateCenteringBoundary(true);
980 return true;
981 }
982}
983
984
985bool
986GNEAdditionalHandler::buildClosingLaneReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& closedLaneID, SVCPermissions permissions) {
987 // get rerouter interval parent
988 GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
989 // get closed lane
990 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(closedLaneID, false);
991 // check parents
992 if (lane == nullptr) {
994 } else if (rerouterInterval == nullptr) {
996 } else {
997 // create closing lane reroute
998 GNEAdditional* closingLaneReroute = new GNEClosingLaneReroute(rerouterInterval, lane, permissions);
999 // add it to interval parent depending of allowUndoRedo
1000 if (myAllowUndoRedo) {
1001 myNet->getViewNet()->getUndoList()->begin(closingLaneReroute, TL("add closing lane reroute in '") + lane->getID() + "'");
1002 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingLaneReroute, true), true);
1004 } else {
1005 rerouterInterval->addChildElement(closingLaneReroute);
1006 closingLaneReroute->incRef("buildClosingLaneReroute");
1007 }
1008 // update centering boundary of rerouter parent
1009 rerouterInterval->getParentAdditionals().front()->updateCenteringBoundary(true);
1010 return true;
1011 }
1012}
1013
1014
1015bool
1016GNEAdditionalHandler::buildClosingReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& closedEdgeID, SVCPermissions permissions) {
1017 // get rerouter interval parent
1018 GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1019 // get closed edge
1020 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(closedEdgeID, false);
1021 // check parents
1022 if (edge == nullptr) {
1024 } else if (rerouterInterval == nullptr) {
1026 } else {
1027 // create closing reroute
1028 GNEAdditional* closingLaneReroute = new GNEClosingReroute(rerouterInterval, edge, permissions);
1029 // add it to interval parent depending of allowUndoRedo
1030 if (myAllowUndoRedo) {
1031 myNet->getViewNet()->getUndoList()->begin(closingLaneReroute, TL("add closing reroute in '") + edge->getID() + "'");
1032 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(closingLaneReroute, true), true);
1034 } else {
1035 rerouterInterval->addChildElement(closingLaneReroute);
1036 closingLaneReroute->incRef("buildClosingLaneReroute");
1037 }
1038 // update centering boundary of rerouter parent
1039 rerouterInterval->getParentAdditionals().front()->updateCenteringBoundary(true);
1040 return true;
1041 }
1042}
1043
1044bool
1045GNEAdditionalHandler::buildDestProbReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newEdgeDestinationID, const double probability) {
1046 // get rerouter interval parent
1047 GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1048 // get edge
1049 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(newEdgeDestinationID, false);
1050 // check parents
1051 if (edge == nullptr) {
1052 return writeErrorInvalidParent(SUMO_TAG_DEST_PROB_REROUTE, "", SUMO_TAG_EDGE, newEdgeDestinationID);
1053 } else if (rerouterInterval == nullptr) {
1055 } else {
1056 // create dest probability reroute
1057 GNEAdditional* destProbReroute = new GNEDestProbReroute(rerouterInterval, edge, probability);
1058 // add it to interval parent depending of allowUndoRedo
1059 if (myAllowUndoRedo) {
1060 myNet->getViewNet()->getUndoList()->begin(destProbReroute, TL("add dest prob reroute in '") + edge->getID() + "'");
1061 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(destProbReroute, true), true);
1063 } else {
1064 rerouterInterval->addChildElement(destProbReroute);
1065 destProbReroute->incRef("builDestProbReroute");
1066 }
1067 // update centering boundary of rerouter parent
1068 rerouterInterval->getParentAdditionals().front()->updateCenteringBoundary(true);
1069 return true;
1070 }
1071}
1072
1073
1074bool
1075GNEAdditionalHandler::buildParkingAreaReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newParkignAreaID, const double probability, const bool visible) {
1076 // get rerouter interval parent
1077 GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1078 // get parking area
1079 GNEAdditional* parkingArea = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_PARKING_AREA, newParkignAreaID, false);
1080 // check parents
1081 if (parkingArea == nullptr) {
1083 } else if (rerouterInterval == nullptr) {
1085 } else {
1086 // create parking area reroute
1087 GNEAdditional* parkingAreaReroute = new GNEParkingAreaReroute(rerouterInterval, parkingArea, probability, visible);
1088 // add it to interval parent depending of allowUndoRedo
1089 if (myAllowUndoRedo) {
1090 myNet->getViewNet()->getUndoList()->begin(parkingAreaReroute, TL("add parking area reroute in '") + parkingArea->getID() + "'");
1091 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(parkingAreaReroute, true), true);
1093 } else {
1094 rerouterInterval->addChildElement(parkingAreaReroute);
1095 parkingAreaReroute->incRef("builParkingAreaReroute");
1096 }
1097 // update centering boundary of rerouter parent
1098 rerouterInterval->getParentAdditionals().front()->updateCenteringBoundary(true);
1099 return true;
1100 }
1101}
1102
1103
1104bool
1105GNEAdditionalHandler::buildRouteProbReroute(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& newRouteID, const double probability) {
1106 // get rerouter interval parent
1107 GNEAdditional* rerouterInterval = getRerouterIntervalParent(sumoBaseObject);
1108 // get route parent
1110 // check parents
1111 if (route == nullptr) {
1113 } else if (rerouterInterval == nullptr) {
1115 } else {
1116 // create rout prob reroute
1117 GNEAdditional* routeProbReroute = new GNERouteProbReroute(rerouterInterval, route, probability);
1118 // add it to interval parent depending of allowUndoRedo
1119 if (myAllowUndoRedo) {
1120 myNet->getViewNet()->getUndoList()->begin(routeProbReroute, TL("add route prob reroute in '") + route->getID() + "'");
1121 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbReroute, true), true);
1123 } else {
1124 rerouterInterval->addChildElement(routeProbReroute);
1125 routeProbReroute->incRef("buildRouteProbReroute");
1126 }
1127 // update centering boundary of rerouter parent
1128 rerouterInterval->getParentAdditionals().front()->updateCenteringBoundary(true);
1129 return true;
1130 }
1131}
1132
1133
1134bool
1135GNEAdditionalHandler::buildRouteProbe(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& edgeID, const SUMOTime period,
1136 const std::string& name, const std::string& file, const SUMOTime begin, const std::vector<std::string>& vTypes,
1137 const Parameterised::Map& parameters) {
1138 // check conditions
1139 const auto element = retrieveAdditionalElement({SUMO_TAG_ROUTEPROBE}, id);
1140 if (!checkElement(SUMO_TAG_ROUTEPROBE, element)) {
1141 return false;
1143 return false;
1144 } else {
1145 // get edge
1146 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1147 // check lane
1148 if (edge == nullptr) {
1150 } else if (!checkNegative(SUMO_TAG_ROUTEPROBE, id, SUMO_ATTR_PERIOD, period, true)) {
1151 return false;
1152 } else if (!checkNegative(SUMO_TAG_ROUTEPROBE, id, SUMO_ATTR_BEGIN, begin, true)) {
1153 return false;
1154 } else if (!checkFileName(SUMO_TAG_ROUTEPROBE, id, SUMO_ATTR_FILE, file)) {
1155 return false;
1156 } else {
1157 // build route probe
1158 GNEAdditional* routeProbe = new GNERouteProbe(id, myNet, myFilename, edge, period, name, file, begin, vTypes, parameters);
1159 // insert depending of allowUndoRedo
1160 if (myAllowUndoRedo) {
1161 myNet->getViewNet()->getUndoList()->begin(routeProbe, TL("add route probe '") + id + "'");
1162 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(routeProbe, true), true);
1164 // check if center after creation
1165 if (sumoBaseObject->hasBoolAttribute(GNE_ATTR_CENTER_AFTER_CREATION) &&
1167 myNet->getViewNet()->centerTo(routeProbe->getPositionInView(), false);
1168 }
1169 } else {
1171 edge->addChildElement(routeProbe);
1172 routeProbe->incRef("buildRouteProbe");
1173 }
1174 return true;
1175 }
1176 }
1177}
1178
1179
1180bool
1181GNEAdditionalHandler::buildVariableSpeedSign(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const Position& pos,
1182 const std::vector<std::string>& laneIDs, const std::string& name, const std::vector<std::string>& vTypes, const Parameterised::Map& parameters) {
1183 // check conditions
1184 const auto element = retrieveAdditionalElement({SUMO_TAG_VSS}, id);
1185 if (!checkElement(SUMO_TAG_VSS, element)) {
1186 return false;
1187 } else if (!checkValidAdditionalID(SUMO_TAG_VSS, id)) {
1188 return false;
1189 } else {
1190 // parse lanes
1191 std::vector<GNELane*> lanes = parseLanes(SUMO_TAG_VSS, id, laneIDs);
1192 // check lane
1193 if (lanes.empty()) {
1194 return false;
1195 } else {
1196 // check vTypes
1197 if (!checkListOfVehicleTypes(SUMO_TAG_VSS, id, vTypes)) {
1198 return false;
1199 } else {
1200 // create VSS
1201 GNEAdditional* variableSpeedSign = new GNEVariableSpeedSign(id, myNet, myFilename, pos, name, vTypes, parameters);
1202 // create VSS Symbols
1203 std::vector<GNEAdditional*> VSSSymbols;
1204 for (const auto& lane : lanes) {
1205 VSSSymbols.push_back(new GNEVariableSpeedSignSymbol(variableSpeedSign, lane));
1206 }
1207 // insert depending of allowUndoRedo
1208 if (myAllowUndoRedo) {
1209 myNet->getViewNet()->getUndoList()->begin(variableSpeedSign, TL("add Variable Speed Sign '") + id + "'");
1210 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSign, true), true);
1211 for (const auto& VSSSymbol : VSSSymbols) {
1212 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(VSSSymbol, true), true);
1213 }
1215 } else {
1216 myNet->getAttributeCarriers()->insertAdditional(variableSpeedSign);
1217 variableSpeedSign->incRef("buildVariableSpeedSign");
1218 // add symbols into VSS
1219 for (const auto& VSSSymbol : VSSSymbols) {
1220 variableSpeedSign->addChildElement(VSSSymbol);
1221 }
1222 // add symbols into lanes
1223 for (int i = 0; i < (int)lanes.size(); i++) {
1224 lanes.at(i)->addChildElement(VSSSymbols.at(i));
1225 }
1226 }
1227 }
1228 return true;
1229 }
1230 }
1231}
1232
1233
1234bool
1236 // get VSS parent
1238 // check lane
1239 if (VSS == nullptr) {
1241 } else if (!checkNegative(SUMO_TAG_STEP, VSS->getID(), SUMO_ATTR_TIME, time, true)) {
1242 return false;
1243 } else {
1244 // create Variable Speed Sign
1245 GNEAdditional* variableSpeedSignStep = new GNEVariableSpeedSignStep(VSS, time, speed);
1246 // add it depending of allow undoRedo
1247 if (myAllowUndoRedo) {
1248 myNet->getViewNet()->getUndoList()->begin(variableSpeedSignStep, TL("add VSS Step in '") + VSS->getID() + "'");
1249 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(variableSpeedSignStep, true), true);
1251 } else {
1252 VSS->addChildElement(variableSpeedSignStep);
1253 variableSpeedSignStep->incRef("buildVariableSpeedSignStep");
1254 }
1255 // update centering boundary of VSS parent
1256 VSS->updateCenteringBoundary(true);
1257 return true;
1258 }
1259}
1260
1261
1262bool
1263GNEAdditionalHandler::buildVaporizer(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const SUMOTime beginTime,
1264 const SUMOTime endTime, const std::string& name, const Parameterised::Map& parameters) {
1265 // check conditions
1266 const auto element = retrieveAdditionalElement({SUMO_TAG_VAPORIZER}, edgeID);
1267 if (!checkElement(SUMO_TAG_VAPORIZER, element)) {
1268 return false;
1269 } else if (!checkValidAdditionalID(SUMO_TAG_VAPORIZER, edgeID)) {
1270 return false;
1271 } else {
1272 // get edge
1273 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1274 // check lane
1275 if (edge == nullptr) {
1277 } else if (!checkNegative(SUMO_TAG_VAPORIZER, edge->getID(), SUMO_ATTR_BEGIN, beginTime, true)) {
1278 return false;
1279 } else if (!checkNegative(SUMO_TAG_VAPORIZER, edge->getID(), SUMO_ATTR_END, endTime, true)) {
1280 return false;
1281 } else if (endTime < beginTime) {
1282 return writeError(TLF("Could not build Vaporizer with ID '%' in netedit; begin is greater than end.", edge->getID()));
1283 } else {
1284 // build vaporizer
1285 GNEAdditional* vaporizer = new GNEVaporizer(myNet, myFilename, edge, beginTime, endTime, name, parameters);
1286 // add it depending of allow undoRed
1287 if (myAllowUndoRedo) {
1288 myNet->getViewNet()->getUndoList()->begin(vaporizer, TL("add vaporizer in '") + edge->getID() + "'");
1289 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(vaporizer, true), true);
1291 // check if center after creation
1292 if (sumoBaseObject->hasBoolAttribute(GNE_ATTR_CENTER_AFTER_CREATION) &&
1294 myNet->getViewNet()->centerTo(vaporizer->getPositionInView(), false);
1295 }
1296 } else {
1298 edge->addChildElement(vaporizer);
1299 vaporizer->incRef("buildVaporizer");
1300 }
1301 return true;
1302 }
1303 }
1304}
1305
1306
1307bool
1308GNEAdditionalHandler::buildTAZ(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const PositionVector& shape,
1309 const Position& center, const bool fill, const RGBColor& color, const std::vector<std::string>& edgeIDs,
1310 const std::string& name, const Parameterised::Map& parameters) {
1311 // parse edges
1312 const std::vector<GNEEdge*> edges = parseEdges(SUMO_TAG_TAZ, id, edgeIDs);
1313 if (edges.size() != edgeIDs.size()) {
1314 return false;
1315 } else {
1316 // check TAZShape
1317 PositionVector TAZShape = shape;
1318 if (TAZShape.size() == 0) {
1319 // declare boundary
1320 Boundary TAZBoundary;
1321 for (const auto& edge : edges) {
1322 TAZBoundary.add(edge->getCenteringBoundary());
1323 }
1324 // iterate over children and add sourceSinkEdge boundaries to make a taz shape
1325 for (const auto& sourceSink : sumoBaseObject->getSumoBaseObjectChildren()) {
1326 // check that child is a source or sink elements (to avoid other elements)
1327 if ((sourceSink->getTag() == SUMO_TAG_TAZSOURCE) || (sourceSink->getTag() == SUMO_TAG_TAZSINK)) {
1328 const GNEEdge* sourceSinkEdge = myNet->getAttributeCarriers()->retrieveEdge(sourceSink->getStringAttribute(SUMO_ATTR_ID), false);
1329 if (sourceSinkEdge) {
1330 TAZBoundary.add(sourceSinkEdge->getCenteringBoundary());
1331 }
1332 }
1333 }
1334 // update TAZShape
1335 TAZShape = TAZBoundary.getShape(true);
1336 }
1337 // check TAZ
1338 const auto element = retrieveAdditionalElement({SUMO_TAG_TAZ}, id);
1339 if (!checkElement(SUMO_TAG_TAZ, element)) {
1340 return false;
1341 } else if (!checkValidAdditionalID(SUMO_TAG_TAZ, id)) {
1342 return false;
1343 } else if (TAZShape.size() == 0) {
1344 return writeError(TLF("Could not build TAZ with ID '%' in netedit; Invalid Shape.", id));
1345 } else {
1346 // build TAZ with the given shape
1347 const Position center2 = center == Position::INVALID ? TAZShape.getCentroid() : center;
1348 GNEAdditional* TAZ = new GNETAZ(id, myNet, myFilename, TAZShape, center2, fill, color, name, parameters);
1349 // disable updating geometry of TAZ children during insertion (because in large nets provokes slowdowns)
1351 // add it depending of allow undoRed
1352 if (myAllowUndoRedo) {
1353 myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ '") + id + "'");
1354 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(TAZ, true), true);
1355 // create TAZEdges
1356 for (const auto& edge : edges) {
1357 // create TAZ Source using GNEChange_Additional
1358 GNETAZSourceSink* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
1359 myNet->getViewNet()->getUndoList()->add(new GNEChange_TAZSourceSink(TAZSource, true), true);
1360 // create TAZ Sink using GNEChange_Additional
1361 GNETAZSourceSink* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
1362 myNet->getViewNet()->getUndoList()->add(new GNEChange_TAZSourceSink(TAZSink, true), true);
1363 }
1365 } else {
1367 TAZ->incRef("buildTAZ");
1368 for (const auto& edge : edges) {
1369 // create TAZ Source
1370 GNETAZSourceSink* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, 1);
1372 TAZSource->incRef("buildTAZ");
1373 TAZ->addChildElement(TAZSource);
1374 edge->addChildElement(TAZSource);
1375 // create TAZ Sink
1376 GNETAZSourceSink* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, 1);
1378 TAZSink->incRef("buildTAZ");
1379 TAZ->addChildElement(TAZSink);
1380 edge->addChildElement(TAZSink);
1381 }
1382 }
1383 // enable updating geometry again and update geometry of TAZ
1385 // update TAZ parent
1386 TAZ->updateGeometry();
1387 return true;
1388 }
1389 }
1390}
1391
1392
1393bool
1394GNEAdditionalHandler::buildTAZSource(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const double departWeight) {
1395 // get TAZ parent
1397 // get edge
1398 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1399 // check parents
1400 if (TAZ == nullptr) {
1402 } else if (edge == nullptr) {
1403 return writeErrorInvalidParent(SUMO_TAG_SOURCE, edgeID, SUMO_TAG_EDGE, TAZ->getID());
1404 } else {
1405 // declare TAZ Source
1406 GNETAZSourceSink* existentTAZSource = nullptr;
1407 // first check if already exist a TAZ Source for the given edge and TAZ
1408 for (auto it = edge->getChildTAZSourceSinks().begin(); (it != edge->getChildTAZSourceSinks().end()) && !existentTAZSource; it++) {
1409 if (((*it)->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) && ((*it)->getParentAdditionals().front() == TAZ)) {
1410 existentTAZSource = (*it);
1411 }
1412 }
1413 // check if TAZSource has to be created
1414 if (existentTAZSource == nullptr) {
1415 // Create TAZ only with departWeight
1416 GNETAZSourceSink* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, TAZ, edge, departWeight);
1417 // add it depending of allow undoRed
1418 if (myAllowUndoRedo) {
1419 myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Source in '") + TAZ->getID() + "'");
1420 myNet->getViewNet()->getUndoList()->add(new GNEChange_TAZSourceSink(TAZSource, true), true);
1422 } else {
1424 TAZ->addChildElement(TAZSource);
1425 edge->addChildElement(TAZSource);
1426 TAZSource->incRef("buildTAZSource");
1427 }
1428 } else {
1429 // update TAZ Attribute depending of allow undoRed
1430 if (myAllowUndoRedo) {
1431 myNet->getViewNet()->getUndoList()->begin(TAZ, TL("update TAZ Source in '") + TAZ->getID() + "'");
1432 existentTAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), myNet->getViewNet()->getUndoList());
1434 } else {
1435 existentTAZSource->setAttribute(SUMO_ATTR_WEIGHT, toString(departWeight), nullptr);
1436 }
1437 }
1438 return true;
1439 }
1440}
1441
1442
1443bool
1444GNEAdditionalHandler::buildTAZSink(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID, const double arrivalWeight) {
1445 // get TAZ parent
1447 // get edge
1448 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
1449 // check parents
1450 if (TAZ == nullptr) {
1452 } else if (edge == nullptr) {
1453 return writeErrorInvalidParent(SUMO_TAG_SOURCE, edgeID, SUMO_TAG_EDGE, TAZ->getID());
1454 } else {
1455 // declare TAZ Sink
1456 GNETAZSourceSink* existentTAZSink = nullptr;
1457 // first check if already exist a TAZ Sink for the given edge and TAZ
1458 for (auto it = edge->getChildTAZSourceSinks().begin(); (it != edge->getChildTAZSourceSinks().end()) && !existentTAZSink; it++) {
1459 if (((*it)->getTagProperty()->getTag() == SUMO_TAG_TAZSINK) && ((*it)->getParentAdditionals().front() == TAZ)) {
1460 existentTAZSink = (*it);
1461 }
1462 }
1463 // check if TAZSink has to be created
1464 if (existentTAZSink == nullptr) {
1465 // Create TAZ only with departWeight
1466 GNETAZSourceSink* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, TAZ, edge, arrivalWeight);
1467 // add it depending of allow undoRed
1468 if (myAllowUndoRedo) {
1469 myNet->getViewNet()->getUndoList()->begin(TAZ, TL("add TAZ Sink in '") + TAZ->getID() + "'");
1470 myNet->getViewNet()->getUndoList()->add(new GNEChange_TAZSourceSink(TAZSink, true), true);
1472 } else {
1474 TAZ->addChildElement(TAZSink);
1475 edge->addChildElement(TAZSink);
1476 TAZSink->incRef("buildTAZSink");
1477 }
1478 } else {
1479 // update TAZ Attribute depending of allow undoRed
1480 if (myAllowUndoRedo) {
1481 myNet->getViewNet()->getUndoList()->begin(TAZ, TL("update TAZ Sink in '") + TAZ->getID() + "'");
1482 existentTAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), myNet->getViewNet()->getUndoList());
1484 } else {
1485 existentTAZSink->setAttribute(SUMO_ATTR_WEIGHT, toString(arrivalWeight), nullptr);
1486 }
1487 }
1488 return true;
1489 }
1490}
1491
1492
1493bool
1494GNEAdditionalHandler::buildTractionSubstation(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const Position& pos,
1495 const double voltage, const double currentLimit, const Parameterised::Map& parameters) {
1496 // check conditions
1497 const auto element = retrieveAdditionalElement({SUMO_TAG_TRACTION_SUBSTATION}, id);
1499 return false;
1501 return false;
1502 } else if (!checkNegative(SUMO_TAG_TRACTION_SUBSTATION, id, SUMO_ATTR_VOLTAGE, voltage, true)) {
1503 return false;
1504 } else if (!checkNegative(SUMO_TAG_TRACTION_SUBSTATION, id, SUMO_ATTR_CURRENTLIMIT, currentLimit, true)) {
1505 return false;
1506 } else {
1507 // build traction substation
1508 GNEAdditional* tractionSubstation = new GNETractionSubstation(id, myNet, myFilename, pos, voltage, currentLimit, parameters);
1509 // insert depending of allowUndoRedo
1510 if (myAllowUndoRedo) {
1511 myNet->getViewNet()->getUndoList()->begin(tractionSubstation, TL("add traction substation '") + id + "'");
1512 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(tractionSubstation, true), true);
1514 } else {
1515 myNet->getAttributeCarriers()->insertAdditional(tractionSubstation);
1516 tractionSubstation->incRef("buildTractionSubstation");
1517 }
1518 return true;
1519 }
1520}
1521
1522
1523bool
1524GNEAdditionalHandler::buildOverheadWire(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& substationId,
1525 const std::vector<std::string>& laneIDs, const double startPos, const double endPos, const bool friendlyPos,
1526 const std::vector<std::string>& forbiddenInnerLanes, const Parameterised::Map& parameters) {
1527 // check conditions
1530 return false;
1532 return false;
1533 } else {
1534 // get lanes
1535 const auto lanes = parseLanes(SUMO_TAG_OVERHEAD_WIRE_SECTION, id, laneIDs);
1536 // get traction substation
1537 const auto tractionSubstation = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TRACTION_SUBSTATION, substationId, false);
1538 // check lanes
1539 if (lanes.empty()) {
1540 return false;
1541 } else {
1542 // calculate path
1544 return writeError(TLF("Could not build overhead wire with ID '%' in netedit; Lanes aren't consecutives.", id));
1545 } else if (!checkMultiLanePosition(
1546 startPos, lanes.front()->getParentEdge()->getNBEdge()->getFinalLength(),
1547 endPos, lanes.back()->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
1549 } else if (tractionSubstation == nullptr) {
1551 } else {
1552 // build Overhead Wire
1553 GNEAdditional* overheadWire = new GNEOverheadWire(id, myNet, myFilename, lanes, tractionSubstation, startPos, endPos, friendlyPos, forbiddenInnerLanes, parameters);
1554 // insert depending of allowUndoRedo
1555 if (myAllowUndoRedo) {
1556 myNet->getViewNet()->getUndoList()->begin(overheadWire, TL("add overhead wire '") + id + "'");
1557 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(overheadWire, true), true);
1559 } else {
1561 for (const auto& lane : lanes) {
1562 lane->addChildElement(overheadWire);
1563 }
1564 overheadWire->incRef("buildOverheadWire");
1565 }
1566 }
1567 return true;
1568 }
1569 }
1570}
1571
1572
1573bool
1574GNEAdditionalHandler::buildOverheadWireClamp(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& /* id */, const std::string& /* overheadWireIDStartClamp */,
1575 const std::string& /* laneIDStartClamp */, const std::string& /* overheadWireIDEndClamp */, const std::string& /* laneIDEndClamp */,
1576 const Parameterised::Map& /* parameters */) {
1577 //
1578 return false;
1579}
1580
1581
1582bool
1583GNEAdditionalHandler::buildPolygon(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& id, const std::string& type,
1584 const RGBColor& color, double layer, double angle, const std::string& imgFile, const PositionVector& shape,
1585 bool geo, bool fill, double lineWidth, const std::string& name, const Parameterised::Map& parameters) {
1586 // check conditions
1587 if (type == "jupedsim.walkable_area") {
1588 return buildJpsWalkableArea(sumoBaseObject, id, shape, geo, name, parameters);
1589 } else if (type == "jupedsim.obstacle") {
1590 return buildJpsObstacle(sumoBaseObject, id, shape, geo, name, parameters);
1591 } else {
1592 // check conditions
1593 const auto element = retrieveAdditionalElement(NamespaceIDs::polygons, id);
1594 if (!checkElement(SUMO_TAG_POLY, element)) {
1595 return false;
1596 } else if (!checkValidAdditionalID(SUMO_TAG_POLY, id)) {
1597 return false;
1598 } else if (!checkNegative(SUMO_TAG_POLY, id, SUMO_ATTR_LINEWIDTH, lineWidth, true)) {
1599 return false;
1600 } else {
1601 // create poly
1602 GNEPoly* poly = new GNEPoly(id, myNet, myFilename, type, shape, geo, fill, lineWidth, color, layer, angle, imgFile, name, parameters);
1603 // add it depending of allow undoRed
1604 if (myAllowUndoRedo) {
1605 myNet->getViewNet()->getUndoList()->begin(poly, TL("add polygon '") + id + "'");
1606 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(poly, true), true);
1608 } else {
1609 // insert shape without allowing undo/redo
1611 poly->incRef("addPolygon");
1612 }
1613 return true;
1614 }
1615 }
1616}
1617
1618
1619bool
1620GNEAdditionalHandler::buildPOI(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& type,
1621 const RGBColor& color, const double x, const double y, const std::string& icon, double layer, double angle,
1622 const std::string& imgFile, double width, double height, const std::string& name, const Parameterised::Map& parameters) {
1623 // check conditions
1624 const auto element = retrieveAdditionalElement(NamespaceIDs::POIs, id);
1625 if (!checkElement(SUMO_TAG_POI, element)) {
1626 return false;
1627 } else if (!checkValidAdditionalID(SUMO_TAG_POI, id)) {
1628 return false;
1629 } else if (!checkNegative(SUMO_TAG_POI, id, SUMO_ATTR_WIDTH, width, true)) {
1630 return false;
1631 } else if (!checkNegative(SUMO_TAG_POI, id, SUMO_ATTR_HEIGHT, height, true)) {
1632 return false;
1633 } else if (!checkFileName(SUMO_TAG_POI, id, SUMO_ATTR_IMGFILE, imgFile)) {
1634 return false;
1635 } else {
1636 // parse position
1637 const auto pos = Position(x, y);
1638 // parse icon
1640 // create POI
1641 GNEPOI* POI = new GNEPOI(id, myNet, myFilename, type, color, pos, false, POIIcon, layer, angle, imgFile, width, height, name, parameters);
1642 // add it depending of allow undoRed
1643 if (myAllowUndoRedo) {
1644 myNet->getViewNet()->getUndoList()->begin(POI, TLF("add POI '%'", id));
1645 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POI, true), true);
1647 } else {
1648 // insert shape without allowing undo/redo
1650 POI->incRef("addPOI");
1651 }
1652 return true;
1653 }
1654}
1655
1656
1657bool
1658GNEAdditionalHandler::buildPOILane(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& type,
1659 const RGBColor& color, const std::string& laneID, double posOverLane, const bool friendlyPos, double posLat,
1660 const std::string& icon, double layer, double angle, const std::string& imgFile, double width, double height,
1661 const std::string& name, const Parameterised::Map& parameters) {
1662 // check conditions
1663 const auto element = retrieveAdditionalElement(NamespaceIDs::POIs, id);
1664 if (!checkElement(GNE_TAG_POILANE, element)) {
1665 return false;
1666 } else if (!checkValidAdditionalID(GNE_TAG_POILANE, id)) {
1667 return false;
1668 } else if (!checkNegative(GNE_TAG_POILANE, id, SUMO_ATTR_WIDTH, width, true)) {
1669 return false;
1670 } else if (!checkNegative(GNE_TAG_POILANE, id, SUMO_ATTR_HEIGHT, height, true)) {
1671 return false;
1672 } else if (!checkFileName(GNE_TAG_POILANE, id, SUMO_ATTR_IMGFILE, imgFile)) {
1673 return false;
1674 } else {
1675 // get lane
1676 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
1677 // check lane
1678 if (lane == nullptr) {
1680 } else if (!checkLanePosition(posOverLane, 0, lane->getParentEdge()->getNBEdge()->getFinalLength(), friendlyPos)) {
1682 } else {
1683 // parse icon
1685 // create POI (use GNEAdditional instead GNEPOI for add child references)
1686 GNEAdditional* POILane = new GNEPOI(id, myNet, myFilename, type, color, lane, posOverLane, friendlyPos, posLat, POIIcon, layer,
1687 angle, imgFile, width, height, name, parameters);
1688 // add it depending of allow undoRed
1689 if (myAllowUndoRedo) {
1690 myNet->getViewNet()->getUndoList()->begin(POILane, TLF("add POI lane '%'", id));
1691 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POILane, true), true);
1693 } else {
1694 // insert shape without allowing undo/redo
1696 lane->addChildElement(POILane);
1697 POILane->incRef("buildPOILane");
1698 }
1699 }
1700 return true;
1701 }
1702}
1703
1704
1705bool
1706GNEAdditionalHandler::buildPOIGeo(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const std::string& type,
1707 const RGBColor& color, const double lon, const double lat, const std::string& icon, double layer,
1708 double angle, const std::string& imgFile, double width, double height, const std::string& name,
1709 const Parameterised::Map& parameters) {
1710 // check conditions
1711 const auto element = retrieveAdditionalElement(NamespaceIDs::POIs, id);
1712 if (!checkElement(GNE_TAG_POIGEO, element)) {
1713 return false;
1714 } else if (!checkValidAdditionalID(GNE_TAG_POIGEO, id)) {
1715 return false;
1716 } else if (!checkNegative(GNE_TAG_POIGEO, id, SUMO_ATTR_WIDTH, width, true)) {
1717 return false;
1718 } else if (!checkNegative(GNE_TAG_POIGEO, id, SUMO_ATTR_HEIGHT, height, true)) {
1719 return false;
1720 } else if (!checkFileName(GNE_TAG_POIGEO, id, SUMO_ATTR_IMGFILE, imgFile)) {
1721 return false;
1722 } else if (GeoConvHelper::getFinal().getProjString() == "!") {
1723 return writeError(TLF("Could not build POI with ID '%' in netedit", id) + std::string("; ") + TL("Network requires a geo projection."));
1724 } else {
1725 // parse position
1726 const auto pos = Position(lon, lat);
1727 // parse icon
1729 // create POIGEO
1730 GNEPOI* POIGEO = new GNEPOI(id, myNet, myFilename, type, color, pos, true, POIIcon, layer, angle, imgFile, width, height, name, parameters);
1731 // add it depending of allow undoRed
1732 if (myAllowUndoRedo) {
1733 myNet->getViewNet()->getUndoList()->begin(POIGEO, TLF("add POI GEO '%'", id));
1734 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(POIGEO, true), true);
1736 } else {
1737 // insert shape without allowing undo/redo
1739 POIGEO->incRef("buildPOIGeo");
1740 }
1741 return true;
1742 }
1743}
1744
1745
1746bool
1747GNEAdditionalHandler::buildJpsWalkableArea(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const PositionVector& shape,
1748 bool geo, const std::string& name, const Parameterised::Map& parameters) {
1749 // check conditions
1750 const auto element = retrieveAdditionalElement(NamespaceIDs::polygons, id);
1751 if (!checkElement(GNE_TAG_JPS_WALKABLEAREA, element)) {
1752 return false;
1754 return false;
1755 } else {
1756 // create walkable area
1757 GNEPoly* walkableArea = new GNEPoly(GNE_TAG_JPS_WALKABLEAREA, id, myNet, myFilename, shape, geo, name, parameters);
1758 // add it depending of allow undoRed
1759 if (myAllowUndoRedo) {
1760 myNet->getViewNet()->getUndoList()->begin(walkableArea, TL("add jps walkable area '") + id + "'");
1761 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(walkableArea, true), true);
1763 } else {
1764 // insert shape without allowing undo/redo
1766 walkableArea->incRef("addWalkableArea");
1767 }
1768 return true;
1769 }
1770}
1771
1772
1773bool
1774GNEAdditionalHandler::buildJpsObstacle(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id, const PositionVector& shape,
1775 bool geo, const std::string& name, const Parameterised::Map& parameters) {
1776 // check conditions
1777 const auto element = retrieveAdditionalElement(NamespaceIDs::polygons, id);
1778 if (!checkElement(GNE_TAG_JPS_OBSTACLE, element)) {
1779 return false;
1781 return false;
1782 } else {
1783 // create walkable area
1784 GNEPoly* obstacle = new GNEPoly(GNE_TAG_JPS_OBSTACLE, id, myNet, myFilename, shape, geo, name, parameters);
1785 // add it depending of allow undoRed
1786 if (myAllowUndoRedo) {
1787 myNet->getViewNet()->getUndoList()->begin(obstacle, TL("add jps obstacle '") + id + "'");
1788 myNet->getViewNet()->getUndoList()->add(new GNEChange_Additional(obstacle, true), true);
1790 } else {
1791 // insert shape without allowing undo/redo
1793 obstacle->incRef("addObstacle");
1794 }
1795 return true;
1796 }
1797}
1798
1799
1800bool
1801GNEAdditionalHandler::accessExists(const GNEAdditional* stoppingPlaceParent, const GNEEdge* edge) {
1802 // check if exist another access for the same parent in the given edge
1803 for (const auto& access : stoppingPlaceParent->getChildAdditionals()) {
1804 // check tag
1805 if (access->getTagProperty()->getTag() == SUMO_TAG_ACCESS) {
1806 // check all siblings of the lane
1807 for (const auto& lane : edge->getChildLanes()) {
1808 if (access->getAttribute(SUMO_ATTR_LANE) == lane->getID()) {
1809 return false;
1810 }
1811 }
1812 }
1813 }
1814 return true;
1815}
1816
1817
1818bool
1820 // declare a vector to keep sorted rerouter children
1821 std::vector<std::pair<SUMOTime, SUMOTime>> sortedIntervals;
1822 // iterate over child additional
1823 for (const auto& rerouterChild : rerouter->getChildAdditionals()) {
1824 if (!rerouterChild->getTagProperty()->isSymbol()) {
1825 sortedIntervals.push_back(std::make_pair((SUMOTime)0., (SUMOTime)0.));
1826 // set begin and end
1827 sortedIntervals.back().first = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_BEGIN));
1828 sortedIntervals.back().second = TIME2STEPS(rerouterChild->getAttributeDouble(SUMO_ATTR_END));
1829 }
1830 }
1831 // add new intervals
1832 sortedIntervals.push_back(std::make_pair(newBegin, newEnd));
1833 // sort children
1834 std::sort(sortedIntervals.begin(), sortedIntervals.end());
1835 // check overlapping after sorting
1836 for (int i = 0; i < (int)sortedIntervals.size() - 1; i++) {
1837 if (sortedIntervals.at(i).second > sortedIntervals.at(i + 1).first) {
1838 return false;
1839 }
1840 }
1841 return true;
1842}
1843
1844
1845bool
1846GNEAdditionalHandler::checkLanePosition(double pos, const double length, const double laneLength, const bool friendlyPos) {
1847 if (friendlyPos) {
1848 return true;
1849 }
1850 // adjust from and to (negative means that start at the end of lane and count backward)
1851 if (pos < 0) {
1852 pos += laneLength;
1853 }
1854 // check extremes
1855 if ((pos < 0) || (pos > laneLength)) {
1856 return false;
1857 }
1858 // check pos + length
1859 if ((pos + length) > laneLength) {
1860 return false;
1861 }
1862 // all OK
1863 return true;
1864}
1865
1866
1867bool
1868GNEAdditionalHandler::checkFriendlyPosSmallLanes(double pos, const double length, const double laneLength, const bool friendlyPos) {
1869 if (friendlyPos == true) {
1870 return true;
1871 } else if (OptionsCont::getOptions().getBool("e2.friendlyPos.automatic")) {
1872 // adjust from and to (negative means that start at the end of lane and count backward)
1873 if (pos < 0) {
1874 pos += laneLength;
1875 }
1876 // check extremes
1877 if ((pos < 0) || (pos > laneLength)) {
1878 return true;
1879 }
1880 // check pos + length
1881 if ((pos + length) > laneLength) {
1882 return true;
1883 }
1884 }
1885 return false;
1886}
1887
1888
1889bool
1890GNEAdditionalHandler::checkLaneDoublePosition(double from, double to, const double laneLength, const bool friendlyPos) {
1891 if (friendlyPos) {
1892 return true;
1893 }
1894 // adjust from and to (negative means that start at the end of lane and count backward)
1895 if (from == INVALID_DOUBLE) {
1896 from = 0;
1897 }
1898 if (to == INVALID_DOUBLE) {
1899 to = laneLength;
1900 }
1901 if (from < 0) {
1902 from += laneLength;
1903 }
1904 if (to < 0) {
1905 to += laneLength;
1906 }
1907 if ((to - from) < POSITION_EPS) {
1908 return false;
1909 }
1910 if ((from < 0) || (from > laneLength)) {
1911 return false;
1912 }
1913 if ((to < 0) || (to > laneLength)) {
1914 return false;
1915 }
1916 return true;
1917}
1918
1919
1920void
1921GNEAdditionalHandler::fixLaneDoublePosition(double& from, double& to, const double laneLength) {
1922 // adjust from (negative means that start at the end of lane and count backward)
1923 if (from == INVALID_DOUBLE) {
1924 from = 0;
1925 }
1926 if (to == INVALID_DOUBLE) {
1927 to = laneLength;
1928 }
1929 if (from < 0) {
1930 from += laneLength;
1931 }
1932 if (from < 0) {
1933 from = 0;
1934 } else if (from > laneLength) {
1935 from = laneLength;
1936 }
1937 // adjust to
1938 if (to < 0) {
1939 to += laneLength;
1940 }
1941 if (to < 0) {
1942 to = 0;
1943 } else if (to > laneLength) {
1944 to = laneLength;
1945 }
1946 // to has more priorty as from, and distance between from and to must be >= POSITION_EPS
1947 if ((to - from) < POSITION_EPS) {
1948 if (to >= POSITION_EPS) {
1949 from = to - POSITION_EPS;
1950 } else {
1951 from = 0;
1952 to = POSITION_EPS;
1953 }
1954 }
1955}
1956
1957
1958bool
1959GNEAdditionalHandler::checkMultiLanePosition(double fromPos, const double fromLaneLength, const double toPos, const double tolaneLength, const bool friendlyPos) {
1960 if (friendlyPos) {
1961 return true;
1962 } else {
1963 return (checkLanePosition(fromPos, 0, fromLaneLength, false) && checkLanePosition(toPos, 0, tolaneLength, false));
1964 }
1965}
1966
1967
1970 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
1971 return nullptr;
1972 } else if (!sumoBaseObject->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ID)) {
1973 return nullptr;
1974 } else {
1976 }
1977}
1978
1979
1982 if (sumoBaseObject->getParentSumoBaseObject() == nullptr) {
1983 // parent interval doesn't exist
1984 return nullptr;
1985 } else if (sumoBaseObject->getParentSumoBaseObject()->getParentSumoBaseObject() == nullptr) {
1986 // rerouter parent doesn't exist
1987 return nullptr;
1988 } else if (!sumoBaseObject->getParentSumoBaseObject()->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ID) || // rerouter ID
1989 !sumoBaseObject->getParentSumoBaseObject()->hasTimeAttribute(SUMO_ATTR_BEGIN) || // interval begin
1990 !sumoBaseObject->getParentSumoBaseObject()->hasTimeAttribute(SUMO_ATTR_END)) { // interval end
1991 return nullptr;
1992 } else {
1997 }
1998}
1999
2000
2001std::vector<GNEEdge*>
2002GNEAdditionalHandler::parseEdges(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& edgeIDs) {
2003 std::vector<GNEEdge*> edges;
2004 for (const auto& edgeID : edgeIDs) {
2005 GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
2006 // empty edges aren't allowed. If edge is empty, write error, clear edges and stop
2007 if (edge == nullptr) {
2008 writeError(TLF("Could not build % with ID '%' in netedit; % with ID '%' doesn't exist.", toString(tag), id, toString(SUMO_TAG_EDGE), edgeID));
2009 edges.clear();
2010 return edges;
2011 } else {
2012 edges.push_back(edge);
2013 }
2014 }
2015 return edges;
2016}
2017
2018
2019std::vector<GNELane*>
2020GNEAdditionalHandler::parseLanes(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& laneIDs) {
2021 std::vector<GNELane*> lanes;
2022 for (const auto& laneID : laneIDs) {
2023 GNELane* lane = myNet->getAttributeCarriers()->retrieveLane(laneID, false);
2024 // empty lanes aren't allowed. If lane is empty, write error, clear lanes and stop
2025 if (lane == nullptr) {
2026 writeError(TLF("Could not build % with ID '%' in netedit; % with ID '%' doesn't exist.", toString(tag), id, toString(SUMO_TAG_LANE), laneID));
2027 lanes.clear();
2028 return lanes;
2029 } else {
2030 lanes.push_back(lane);
2031 }
2032 }
2033 return lanes;
2034}
2035
2036
2038GNEAdditionalHandler::retrieveAdditionalElement(const std::vector<SumoXMLTag> tags, const std::string& id) {
2039 for (const auto& tag : tags) {
2040 // retrieve additional element
2041 auto additionalElement = myNet->getAttributeCarriers()->retrieveAdditional(tag, id, false);
2042 if (additionalElement) {
2043 return additionalElement;
2044 }
2045 }
2046 return nullptr;
2047}
2048
2049
2050bool
2052 if (additionalElement) {
2053 if (myOverwriteElements) {
2054 // delete element
2055 myNet->deleteAdditional(additionalElement, myNet->getViewNet()->getUndoList());
2056 } else if (myRemainElements) {
2057 // duplicated demand
2058 return writeWarningDuplicated(tag, additionalElement->getID(), additionalElement->getTagProperty()->getTag());
2059 } else {
2060 // open overwrite dialog
2061 GNEOverwriteElement overwriteElementDialog(this, additionalElement);
2062 // continue depending of result
2063 if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {
2064 // delete element
2065 myNet->deleteAdditional(additionalElement, myNet->getViewNet()->getUndoList());
2066 } else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {
2067 // duplicated demand
2068 return writeWarningDuplicated(tag, additionalElement->getID(), additionalElement->getTagProperty()->getTag());
2069 } else {
2070 return false;
2071 }
2072 }
2073 }
2074 return true;
2075}
2076
2077/****************************************************************************/
const unsigned char E3[]
Definition E3.cpp:22
long long int SUMOTime
Definition GUI.h:36
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
#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
POIIcon
POI icons.
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
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ 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
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_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_POILANE
Point of interest over Lane.
@ 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
@ SUMO_ATTR_LANE
@ GNE_ATTR_CENTER_AFTER_CREATION
flag to center camera after element creation
@ SUMO_ATTR_FILE
@ SUMO_ATTR_JAM_DIST_THRESHOLD
@ SUMO_ATTR_PARKING_LENGTH
@ SUMO_ATTR_VOLTAGE
voltage of the traction substation [V]
@ 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_IMGFILE
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_CHARGEDELAY
Delay in the charge of charging stations (different of waiting time)
@ SUMO_ATTR_TIME
trigger: the time of the step
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
const double SUMO_const_laneWidth
Definition StdDefs.h:52
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
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:75
PositionVector getShape(const bool closeShape) const
get position vector (shape) based on this boundary
Definition Boundary.cpp:444
bool writeError(const std::string &error)
write error and enable error creating element
bool checkValidDetectorID(const SumoXMLTag tag, const std::string &value)
check if the given detector ID is valid
bool writeErrorInvalidParent(const SumoXMLTag tag, const std::string &id, const SumoXMLTag parentTag, const std::string &parentID)
write error "invalid parent element" giving ids of current and parent element
bool checkListOfVehicleTypes(const SumoXMLTag tag, const std::string &id, const std::vector< std::string > &vTypeIDs)
check list of IDs
bool writeWarningDuplicated(const SumoXMLTag tag, const std::string &id, const SumoXMLTag checkedTag)
write warning duplicated element
bool myOverwriteElements
overwrite elements
bool checkValidAdditionalID(const SumoXMLTag tag, const std::string &value)
check if the given additional ID is valid
bool checkFileName(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const std::string &value)
check if the given filename is valid
bool writeErrorInvalidPosition(const SumoXMLTag tag, const std::string &id)
write error "invalid position"
const std::string myFilename
filename
bool checkNegative(const SumoXMLTag tag, const std::string &id, const SumoXMLAttr attribute, const int value, const bool canBeZero)
check if the given int value is NOT negative
bool myRemainElements
remain elements
SUMOTime getTimeAttribute(const SumoXMLAttr attr) const
get time attribute
bool hasBoolAttribute(const SumoXMLAttr attr) const
check if current SumoBaseObject has the given bool attribute
bool hasStringAttribute(const SumoXMLAttr attr) const
has function
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
bool getBoolAttribute(const SumoXMLAttr attr) const
get bool attribute
const std::string & getStringAttribute(const SumoXMLAttr attr) const
get string attribute
const std::vector< SumoBaseObject * > & getSumoBaseObjectChildren() const
get SumoBaseObject children
GNEAdditional * retrieveAdditionalElement(const std::vector< SumoXMLTag > tags, const std::string &id)
get element by ID
bool 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.
bool 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
bool buildClosingReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &closedEdgeID, SVCPermissions permissions)
builds a closing edge reroute
GNEAdditional * getRerouterIntervalParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject) const
get rerouter interval parent
std::vector< GNELane * > parseLanes(const SumoXMLTag tag, const std::string &id, const std::vector< std::string > &laneIDs)
parse lanes
void fixLaneDoublePosition(double &from, double &to, const double laneLengt)
fix the given positions over lane
bool checkFriendlyPosSmallLanes(double pos, const double length, const double laneLength, const bool friendlyPos)
check if enable friendly pos in small lanes
bool 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, const double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI using the given values.
bool 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, const double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI in GEO coordinaten using the given values.
bool 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 double angle, const Parameterised::Map &parameters)
Builds a train stop.
bool buildTAZSource(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const double departWeight)
Builds a TAZSource (Traffic Assignment Zone)
bool 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
bool 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
GNEAdditional * getAdditionalParent(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, SumoXMLTag tag) const
get additional parent
bool buildMultiLaneDetectorE2(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &id, const std::vector< std::string > &laneIDs, 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::vector< std::string > &nextEdges, const std::string &detectPersons, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos, const bool show, const Parameterised::Map &parameters)
Builds a multi-lane Area Detector (E2)
bool 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::vector< std::string > &nextEdges, const std::string &detectPersons, const std::string &name, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a induction loop detector (E1)
bool buildVariableSpeedSignStep(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOTime time, const double speed)
Builds a VariableSpeedSign Step.
bool 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 double width, const double height, const std::string &name, const Parameterised::Map &parameters)
Builds a POI over lane using the given values.
bool 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 double angle, const Parameterised::Map &parameters)
Builds a bus stop.
bool 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.
static bool accessExists(const GNEAdditional *stoppingPlaceParent, const GNEEdge *edge)
check if a GNEAccess can be created in the given edge
bool buildDetectorEntry(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &laneID, const double pos, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a entry detector (E3)
bool 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 double angle, const Parameterised::Map &parameters)
Builds a container stop.
bool 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
bool 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
bool buildDestProbReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newEdgeDestinationID, const double probability)
builds a dest prob reroute
bool buildClosingLaneReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &closedLane, SVCPermissions permissions)
builds a closing lane reroute
bool buildCalibratorFlow(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOVehicleParameter &vehicleParameter)
builds a calibrator flow
bool 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)
bool buildParkingAreaReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newParkignAreaID, const double probability, const bool visible)
builds a parking area reroute
GNEAdditionalHandler()=delete
invalidate default constructo
bool buildDetectorExit(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &laneID, const double pos, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a exit detector (E3)
bool 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.
const bool myAllowUndoRedo
allow undo/redo
bool checkLaneDoublePosition(double from, const double to, const double laneLength, const bool friendlyPos)
check if the given positions over a lane is valid
std::vector< GNEEdge * > parseEdges(const SumoXMLTag tag, const std::string &id, const std::vector< std::string > &edgeIDs)
parse edges
bool postParserTasks()
run post parser tasks
bool 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
bool checkLanePosition(double pos, const double length, const double laneLength, const bool friendlyPos)
check if the given position over a lane is valid
bool buildRerouterInterval(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const SUMOTime begin, const SUMOTime end)
builds a rerouter interval
bool 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::vector< std::string > &nextEdges, const std::string &detectPersons, const std::string &name, const bool friendlyPos, const Parameterised::Map &parameters)
Builds a Instant Induction Loop Detector (E1Instant)
bool buildTAZSink(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &edgeID, const double arrivalWeight)
Builds a TAZSink (Traffic Assignment Zone)
bool checkElement(const SumoXMLTag tag, GNEAdditional *additional)
check if element exist, and if overwrite
bool 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::vector< std::string > &nextEdges, const std::string &detectPersons, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const double jamThreshold, const bool friendlyPos, const bool show, const Parameterised::Map &parameters)
Builds a single-lane Area Detector (E2)
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
GNENet * myNet
pointer to GNENet
bool 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.
bool 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.
bool 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.
bool 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)
bool 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)
bool 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 std::vector< std::string > &vTypes, const Parameterised::Map &parameters)
builds a Route probe
bool 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::vector< std::string > &nextEdges, const std::string &detectPersons, const std::string &name, const SUMOTime timeThreshold, const double speedThreshold, const bool openEntry, const bool expectedArrival, const Parameterised::Map &parameters)
Builds a multi entry exit detector (E3)
bool buildRouteProbReroute(const CommonXMLStructure::SumoBaseObject *sumoBaseObject, const std::string &newRouteID, const double probability)
builds a route prob reroute
bool 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 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.
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
virtual void updateCenteringBoundary(const bool updateGrid)=0
update centering boundary (implies change in RTREE)
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)
const std::string & getTagStr() const
get tag assigned to this object in string format
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
virtual void updateGeometry()=0
update pre-computed geometry information
static GNEBusStop * buildTrainStop(GNENet *net)
default constructor
static GNEBusStop * buildBusStop(GNENet *net)
default constructor
Result getResult() const
get result to indicate if this dialog was closed accepting or rejecting changes
Definition GNEDialog.cpp:96
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:753
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNEEdge.cpp:626
const GNEHierarchicalContainerParents< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
const GNEHierarchicalContainerChildren< GNEAdditional * > & getChildAdditionals() const
return child additionals
const GNEHierarchicalContainerChildrenSet< GNETAZSourceSink * > & getChildTAZSourceSinks() const
return child TAZSourceSinks (Set)
void addChildElement(ChildType *element)
add child without updating parent (ONLY used if we're creating elements without undo-redo)
bool allowPedestrians() const
check if current lane allow pedestrians
Definition GNELane.cpp:220
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:214
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.
void insertTAZSourceSink(GNETAZSourceSink *sourceSink)
Insert a sourceSink element in container.
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:712
void disableUpdateGeometry()
disable update geometry of elements after inserting or removing an element in net
Definition GNENet.cpp:2901
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
void enableUpdateGeometry()
Definition GNENet.cpp:2895
void incRef(const std::string &debugMsg="")
Increase reference.
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
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...
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:4884
static const std::vector< SumoXMLTag > busStops
busStops namespace
static const std::vector< SumoXMLTag > laneAreaDetectors
lane area detectors namespace
static const std::vector< SumoXMLTag > POIs
POIs namespace.
static const std::vector< SumoXMLTag > calibrators
calibrators namespace
static const std::vector< SumoXMLTag > polygons
polygon namespace
static OptionsCont & getOptions()
Retrieves the options.
C++ TraCI client API implementation.
std::map< std::string, std::string > Map
parameters map
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:323
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, bool extrapolateBeyond=false) 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 StringBijection< ChargeType > ChargeTypes
charge type
static StringBijection< POIIcon > POIIcons
POI icon values.
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
bool hasString(const std::string &str) const
check if the given string exist
T get(const std::string &str) const
get key