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