Eclipse SUMO - Simulation of Urban MObility
GNENet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // A visual container for GNE-network-components such as GNEEdge and GNEJunction.
19 // GNE components wrap netbuild-components and supply visualisation and editing
20 // capabilities (adapted from GUINet)
21 //
22 // WorkrouteFlow (rough draft)
23 // use NILoader to fill
24 // do netedit stuff
25 // call compute to save results
26 //
27 /****************************************************************************/
28 #include <netbuild/NBAlgorithms.h>
29 #include <netbuild/NBNetBuilder.h>
52 #include <netwrite/NWFrame.h>
53 #include <netwrite/NWWriter_SUMO.h>
54 #include <netwrite/NWWriter_XML.h>
59 
60 #include "GNEApplicationWindow.h"
61 #include "GNENet.h"
62 #include "GNEViewNet.h"
63 #include "GNEUndoList.h"
64 #include "GNEViewParent.h"
65 
66 
67 // ===========================================================================
68 // FOX callback mapping
69 // ===========================================================================
70 
71 FXIMPLEMENT_ABSTRACT(GNENetHelper::GNEChange_ReplaceEdgeInTLS, GNEChange, nullptr, 0)
72 
73 // ===========================================================================
74 // static members
75 // ===========================================================================
76 
77 const double GNENet::Z_INITIALIZED = 1;
78 
79 // ===========================================================================
80 // member method definitions
81 // ===========================================================================
82 
83 GNENet::GNENet(NBNetBuilder* netBuilder) :
85  myViewNet(nullptr),
86  myNetBuilder(netBuilder),
87  myAttributeCarriers(new GNENetHelper::AttributeCarriers(this)),
88  myPathManager(new GNEPathManager(this)),
89  myJunctionIDCounter(0),
90  myEdgeIDCounter(0),
91  myNeedRecompute(true),
92  myNetSaved(true),
93  myAdditionalsSaved(true),
94  myTLSProgramsSaved(true),
95  myDemandElementsSaved(true),
96  myDataElementsSaved(true),
97  myUpdateGeometryEnabled(true),
98  myUpdateDataEnabled(true) {
99  // set net in gIDStorage
101  // Write GL debug information
102  WRITE_GLDEBUG("initJunctionsAndEdges function called in GNENet constructor");
103  // init junction and edges
104  initJunctionsAndEdges();
105  // check Z boundary
106  if (myZBoundary.ymin() != Z_INITIALIZED) {
107  myZBoundary.add(0, 0);
108  }
109 
110 }
111 
112 
114  // delete path manager
115  delete myPathManager;
116  // delete AttributeCarriers
117  delete myAttributeCarriers;
118  // show extra information for tests
119  WRITE_DEBUG("Deleting net builder in GNENet destructor");
120  delete myNetBuilder;
121 }
122 
123 
126  return myAttributeCarriers;
127 }
128 
129 
132  return myPathManager;
133 }
134 
135 
136 const Boundary&
138  // SUMORTree is also a Boundary
139  return myGrid;
140 }
141 
142 
143 SUMORTree&
145  return myGrid;
146 }
147 
148 const std::map<std::string, int>&
151 }
152 
153 
156  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
157  buildPopupHeader(ret, app);
159  buildPositionCopyEntry(ret, false);
160  return ret;
161 }
162 
163 
166  // Nets lanes don't have attributes
167  GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
168  // close building
169  ret->closeBuilding();
170  return ret;
171 }
172 
173 
174 void
176  // nothing to drawn
177 }
178 
179 
180 double
182  return 1;
183 }
184 
185 
186 Boundary
188  return getBoundary();
189 }
190 
191 
192 void
193 GNENet::expandBoundary(const Boundary& newBoundary) {
194  myGrid.add(newBoundary);
195 }
196 
197 
198 const Boundary&
200  return myZBoundary;
201 }
202 
203 
204 void
206  // @todo let Boundary class track z-coordinate natively
207  if (z != 0) {
209  }
210 }
211 
212 
215  // get junction prefix
216  const std::string junctionPrefix = OptionsCont::getOptions().getString("node-prefix");
217  // generate new ID
218  while (myAttributeCarriers->getJunctions().count(junctionPrefix + toString(myJunctionIDCounter)) != 0) {
220  }
221  // create new NBNode
222  NBNode* nbn = new NBNode(junctionPrefix + toString(myJunctionIDCounter), pos);
223  GNEJunction* junction = new GNEJunction(this, nbn);
224  undoList->add(new GNEChange_Junction(junction, true), true);
225  return junction;
226 }
227 
228 
229 GNEEdge*
230 GNENet::createEdge(GNEJunction* src, GNEJunction* dest, GNEEdge* edgeTemplate, GNEUndoList* undoList,
231  const std::string& suggestedName, bool wasSplit, bool allowDuplicateGeom, bool recomputeConnections) {
232  // get edge prefix
233  const std::string edgePrefix = OptionsCont::getOptions().getString("edge-prefix");
234  // get edge infix
235  std::string edgeInfix = OptionsCont::getOptions().getString("edge-infix");
236  // prevent duplicate edge (same geometry)
237  for (const auto& outgoingEdge : src->getNBNode()->getOutgoingEdges()) {
238  if (outgoingEdge->getToNode() == dest->getNBNode() && outgoingEdge->getGeometry().size() == 2) {
239  if (!allowDuplicateGeom) {
240  return nullptr;
241  }
242  }
243  }
244  // check if exist opposite edge
245  const GNEEdge* oppositeEdge = myAttributeCarriers->retrieveEdge(dest, src, false);
246  // declare edge id
247  std::string edgeID;
248  // update id
249  if (oppositeEdge) {
250  // avoid ids with "--..."
251  if ((oppositeEdge->getID().size() > 1) && (oppositeEdge->getID().front() == '-')) {
252  edgeID = oppositeEdge->getID().substr(1);
253  } else {
254  edgeID = "-" + oppositeEdge->getID();
255  }
256  // check if already exist an edge with edgeID
257  if (myAttributeCarriers->getEdges().count(edgeID) > 0) {
258  int counter = 0;
259  // generate new ID using edgeID and counter
260  while (myAttributeCarriers->getEdges().count(edgeID + toString(counter)) > 0) {
261  counter++;
262  }
263  edgeID = edgeID + toString(counter);
264  }
265  } else if ((suggestedName.size() > 0) && (myAttributeCarriers->retrieveEdge(suggestedName, false) == nullptr)) {
266  edgeID = suggestedName;
267  } else if (edgeInfix.size() > 0) {
268  // permit empty infix by setting it to <SPACE>
269  edgeInfix = StringUtils::trim(edgeInfix);
270  // check if exist edge with id <fromNodeID><infix><toNodeID>
271  if (myAttributeCarriers->getEdges().count(src->getID() + edgeInfix + dest->getID()) == 0) {
272  edgeID = src->getID() + edgeInfix + dest->getID();
273  } else {
274  int counter = 0;
275  // generate new ID using edgeInfix and counter
276  while (myAttributeCarriers->getEdges().count(src->getID() + edgeInfix + toString(counter) + dest->getID()) != 0) {
277  myEdgeIDCounter++;
278  }
279  edgeID = src->getID() + edgeInfix + toString(counter) + dest->getID();
280  }
281  } else {
282  // generate new ID
283  while (myAttributeCarriers->getEdges().count(edgePrefix + toString(myEdgeIDCounter)) != 0) {
284  myEdgeIDCounter++;
285  }
286  edgeID = edgePrefix + toString(myEdgeIDCounter);
287  }
288  GNEEdge* edge;
289  // check if there is a template edge
290  if (edgeTemplate) {
291  // create NBEdgeTemplate
292  NBEdge* nbe = new NBEdge(edgeID, src->getNBNode(), dest->getNBNode(), edgeTemplate->getNBEdge());
293  edge = new GNEEdge(this, nbe, wasSplit);
294  } else {
295  // default if no template is given
296  const OptionsCont& oc = OptionsCont::getOptions();
297  double defaultSpeed = oc.getFloat("default.speed");
298  const std::string defaultType = oc.getString("default.type");
299  const int defaultNrLanes = oc.getInt("default.lanenumber");
300  const int defaultPriority = oc.getInt("default.priority");
301  const double defaultWidth = NBEdge::UNSPECIFIED_WIDTH;
302  const double defaultOffset = NBEdge::UNSPECIFIED_OFFSET;
304  // build NBEdge
305  NBEdge* nbe = new NBEdge(edgeID, src->getNBNode(), dest->getNBNode(),
306  defaultType, defaultSpeed,
307  defaultNrLanes, defaultPriority,
308  defaultWidth, defaultOffset, spread);
309  // create edge
310  edge = new GNEEdge(this, nbe, wasSplit);
311  }
312  // add edge usin undo list
313  undoList->begin(GUIIcon::EDGE, "create " + toString(SUMO_TAG_EDGE));
314  undoList->add(new GNEChange_Edge(edge, true), true);
315  // recompute connection
316  if (recomputeConnections) {
317  src->setLogicValid(false, undoList);
318  dest->setLogicValid(false, undoList);
319  }
321  undoList->end();
322  return edge;
323 }
324 
325 
326 void
328  // we have to delete all incident edges because they cannot exist without that junction
329  // all deletions must be undone/redone together so we start a new command group
330  // @todo if any of those edges are dead-ends should we remove their orphan junctions as well?
331  undoList->begin(GUIIcon::MODEDELETE, "delete " + toString(SUMO_TAG_JUNCTION));
332  // invalidate junction path elements
334  // delete all crossings vinculated with junction
335  while (junction->getGNECrossings().size() > 0) {
336  deleteCrossing(junction->getGNECrossings().front(), undoList);
337  }
338  // find all crossings of neightbour junctions that shares an edge of this junction
339  std::vector<GNECrossing*> crossingsToRemove;
340  std::vector<GNEJunction*> junctionNeighbours = junction->getJunctionNeighbours();
341  for (const auto& junctionNeighbour : junctionNeighbours) {
342  // iterate over crossing of neighbour juntion
343  for (const auto& crossing : junctionNeighbour->getGNECrossings()) {
344  // if at least one of the edges of junction to remove belongs to a crossing of the neighbour junction, delete it
345  if (crossing->checkEdgeBelong(junctionNeighbour->getChildEdges())) {
346  crossingsToRemove.push_back(crossing);
347  }
348  }
349  }
350  // delete crossings top remove
351  for (const auto& crossing : crossingsToRemove) {
352  deleteCrossing(crossing, undoList);
353  }
354  // deleting edges changes in the underlying EdgeVector so we have to make a copy
355  const EdgeVector incidentEdges = junction->getNBNode()->getEdges();
356  for (const auto& edge : incidentEdges) {
357  deleteEdge(myAttributeCarriers->getEdges().at(edge->getID()), undoList, true);
358  }
359  // remove any traffic lights from the traffic light container (avoids lots of warnings)
361  // delete edge
362  undoList->add(new GNEChange_Junction(junction, false), true);
363  undoList->end();
364 }
365 
366 
367 void
368 GNENet::deleteEdge(GNEEdge* edge, GNEUndoList* undoList, bool recomputeConnections) {
369  undoList->begin(GUIIcon::MODEDELETE, "delete " + toString(SUMO_TAG_EDGE));
370  // iterate over lanes
371  for (const auto& lane : edge->getLanes()) {
372  // invalidate lane path elements
374  // delete lane additionals
375  while (lane->getChildAdditionals().size() > 0) {
376  deleteAdditional(lane->getChildAdditionals().front(), undoList);
377  }
378  // delete lane shapes
379  while (lane->getChildShapes().size() > 0) {
380  deleteShape(lane->getChildShapes().front(), undoList);
381  }
382  // delete lane demand elements
383  while (lane->getChildDemandElements().size() > 0) {
384  deleteDemandElement(lane->getChildDemandElements().front(), undoList);
385  }
386  // delete lane generic data elements
387  while (lane->getChildGenericDatas().size() > 0) {
388  deleteGenericData(lane->getChildGenericDatas().front(), undoList);
389  }
390  }
391  // delete edge child additionals
392  while (edge->getChildAdditionals().size() > 0) {
393  deleteAdditional(edge->getChildAdditionals().front(), undoList);
394  }
395  // delete edge child shapes
396  while (edge->getChildShapes().size() > 0) {
397  deleteShape(edge->getChildShapes().front(), undoList);
398  }
399  // delete edge child demand elements
400  while (edge->getChildDemandElements().size() > 0) {
401  deleteDemandElement(edge->getChildDemandElements().front(), undoList);
402  }
403  // delete edge child generic datas
404  while (edge->getChildGenericDatas().size() > 0) {
405  deleteGenericData(edge->getChildGenericDatas().front(), undoList);
406  }
407  // remove edge from crossings related with this edge
408  edge->getFromJunction()->removeEdgeFromCrossings(edge, undoList);
409  edge->getToJunction()->removeEdgeFromCrossings(edge, undoList);
410  // update affected connections
411  if (recomputeConnections) {
412  edge->getFromJunction()->setLogicValid(false, undoList);
413  edge->getToJunction()->setLogicValid(false, undoList);
414  } else {
415  edge->getFromJunction()->removeConnectionsTo(edge, undoList, true);
416  edge->getFromJunction()->removeConnectionsFrom(edge, undoList, true);
417  }
418  // if junction source is a TLS and after deletion will have only an edge, remove TLS
419  if (edge->getFromJunction()->getNBNode()->isTLControlled() && (edge->getFromJunction()->getGNEOutgoingEdges().size() <= 1)) {
421  }
422  // if junction destiny is a TLS and after deletion will have only an edge, remove TLS
423  if (edge->getToJunction()->getNBNode()->isTLControlled() && (edge->getToJunction()->getGNEIncomingEdges().size() <= 1)) {
425  }
426  // Delete edge
427  undoList->add(new GNEChange_Edge(edge, false), true);
428  // remove edge requires always a recompute (due geometry and connections)
430  // finish delete edge
431  undoList->end();
432 }
433 
434 
435 void
437  undoList->begin(GUIIcon::EDGE, "replace " + toString(SUMO_TAG_EDGE));
439  // iterate over lane
440  for (const auto& lane : which->getLanes()) {
441  // replace in additionals
442  std::vector<GNEAdditional*> copyOfLaneAdditionals = lane->getChildAdditionals();
443  for (const auto& additional : copyOfLaneAdditionals) {
444  undoList->changeAttribute(new GNEChange_Attribute(additional, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex())));
445  }
446  // replace in shapes
447  std::vector<GNEShape*> copyOfLaneShapes = lane->getChildShapes();
448  for (const auto& shape : copyOfLaneShapes) {
449  undoList->changeAttribute(new GNEChange_Attribute(shape, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex())));
450  }
451  // replace in demand elements
452  std::vector<GNEDemandElement*> copyOfLaneDemandElements = lane->getChildDemandElements();
453  for (const auto& demandElement : copyOfLaneDemandElements) {
454  undoList->changeAttribute(new GNEChange_Attribute(demandElement, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex())));
455  }
456  // replace in generic datas
457  std::vector<GNEGenericData*> copyOfLaneGenericDatas = lane->getChildGenericDatas();
458  for (const auto& demandElement : copyOfLaneGenericDatas) {
459  undoList->changeAttribute(new GNEChange_Attribute(demandElement, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex())));
460  }
461  }
462  // replace in edge additionals children
463  while (which->getChildAdditionals().size() > 0) {
464  undoList->changeAttribute(new GNEChange_Attribute(which->getChildAdditionals().front(), SUMO_ATTR_EDGE, by->getID()));
465  }
466  // replace in edge shapes children
467  while (which->getChildShapes().size() > 0) {
468  undoList->changeAttribute(new GNEChange_Attribute(which->getChildShapes().front(), SUMO_ATTR_EDGE, by->getID()));
469  }
470  // replace in edge demand elements children
471  while (which->getChildDemandElements().size() > 0) {
472  undoList->changeAttribute(new GNEChange_Attribute(which->getChildDemandElements().front(), SUMO_ATTR_EDGE, by->getID()));
473  }
474  // replace in edge demand elements children
475  while (which->getChildGenericDatas().size() > 0) {
476  undoList->changeAttribute(new GNEChange_Attribute(which->getChildGenericDatas().front(), SUMO_ATTR_EDGE, by->getID()));
477  }
478  // replace in rerouters
479  for (const auto& rerouter : which->getParentAdditionals()) {
480  replaceInListAttribute(rerouter, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
481  }
482  // replace in crossings
483  for (const auto& crossing : which->getToJunction()->getGNECrossings()) {
484  // if at least one of the edges of junction to remove belongs to a crossing of the source junction, delete it
485  replaceInListAttribute(crossing, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
486  }
487  // fix connections (make a copy because they will be modified
488  std::vector<NBEdge::Connection> NBConnections = which->getNBEdge()->getConnections();
489  for (const auto& NBConnection : NBConnections) {
490  undoList->add(new GNEChange_Connection(which, NBConnection, false, false), true);
491  undoList->add(new GNEChange_Connection(by, NBConnection, false, true), true);
492  }
493  undoList->add(new GNENetHelper::GNEChange_ReplaceEdgeInTLS(getTLLogicCont(), which->getNBEdge(), by->getNBEdge()), true);
494  // Delete edge
495  undoList->add(new GNEChange_Edge(which, false), true);
496  // finish replace edge
497  undoList->end();
498 }
499 
500 
501 void
502 GNENet::deleteLane(GNELane* lane, GNEUndoList* undoList, bool recomputeConnections) {
503  GNEEdge* edge = lane->getParentEdge();
504  if (edge->getNBEdge()->getNumLanes() == 1) {
505  // remove the whole edge instead
506  deleteEdge(edge, undoList, recomputeConnections);
507  } else {
508  undoList->begin(GUIIcon::MODEDELETE, "delete " + toString(SUMO_TAG_LANE));
509  // invalidate lane path elements
511  // delete lane additional children
512  while (lane->getChildAdditionals().size() > 0) {
513  deleteAdditional(lane->getChildAdditionals().front(), undoList);
514  }
515  // delete lane shape children
516  while (lane->getChildShapes().size() > 0) {
517  deleteShape(lane->getChildShapes().front(), undoList);
518  }
519  // delete lane demand element children
520  while (lane->getChildDemandElements().size() > 0) {
521  deleteDemandElement(lane->getChildDemandElements().front(), undoList);
522  }
523  // delete lane generic data children
524  while (lane->getChildGenericDatas().size() > 0) {
525  deleteGenericData(lane->getChildGenericDatas().front(), undoList);
526  }
527  // update affected connections
528  if (recomputeConnections) {
529  edge->getFromJunction()->setLogicValid(false, undoList);
530  edge->getToJunction()->setLogicValid(false, undoList);
531  } else {
532  edge->getFromJunction()->removeConnectionsTo(edge, undoList, true, lane->getIndex());
533  edge->getToJunction()->removeConnectionsFrom(edge, undoList, true, lane->getIndex());
534  }
535  // delete lane
536  const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
537  undoList->add(new GNEChange_Lane(edge, lane, laneAttrs, false, recomputeConnections), true);
538  // remove lane requires always a recompute (due geometry and connections)
540  undoList->end();
541  }
542 }
543 
544 
545 void
547  undoList->begin(GUIIcon::MODEDELETE, "delete " + toString(SUMO_TAG_CONNECTION));
548  // obtain NBConnection to remove
549  NBConnection deleted = connection->getNBConnection();
550  GNEJunction* junctionDestiny = connection->getEdgeFrom()->getToJunction();
551  junctionDestiny->markAsModified(undoList);
552  undoList->add(new GNEChange_Connection(connection->getEdgeFrom(), connection->getNBEdgeConnection(), connection->isAttributeCarrierSelected(), false), true);
553  junctionDestiny->invalidateTLS(undoList, deleted);
554  // remove connection requires always a recompute (due geometry and connections)
556  undoList->end();
557 }
558 
559 
560 void
562  undoList->begin(GUIIcon::MODEDELETE, "delete crossing");
563  // remove it using GNEChange_Crossing
564  undoList->add(new GNEChange_Crossing(
565  crossing->getParentJunction(), crossing->getNBCrossing()->edges,
566  crossing->getNBCrossing()->width, crossing->getNBCrossing()->priority,
567  crossing->getNBCrossing()->customTLIndex,
568  crossing->getNBCrossing()->customTLIndex2,
569  crossing->getNBCrossing()->customShape,
570  crossing->isAttributeCarrierSelected(),
571  false), true);
572  // remove crossing requires always a recompute (due geometry and connections)
574  undoList->end();
575 }
576 
577 
578 void
580  undoList->begin(GUIIcon::MODEDELETE, "delete " + additional->getTagStr());
581  // remove all demand element children of this additional deleteDemandElement this function recursively
582  while (additional->getChildDemandElements().size() > 0) {
583  deleteDemandElement(additional->getChildDemandElements().front(), undoList);
584  }
585  // remove all generic data children of this additional deleteGenericData this function recursively
586  while (additional->getChildGenericDatas().size() > 0) {
587  deleteGenericData(additional->getChildGenericDatas().front(), undoList);
588  }
589  // remove all additional children of this additional calling this function recursively
590  while (additional->getChildAdditionals().size() > 0) {
591  deleteAdditional(additional->getChildAdditionals().front(), undoList);
592  }
593  // remove additional
594  undoList->add(new GNEChange_Additional(additional, false), true);
595  undoList->end();
596 }
597 
598 
599 void
601  undoList->begin(GUIIcon::MODEDELETE, "delete " + shape->getTagStr());
602  // delete shape
603  undoList->add(new GNEChange_Shape(shape, false), true);
604  undoList->end();
605 }
606 
607 
608 void
610  undoList->begin(GUIIcon::MODEDELETE, "delete " + TAZElement->getTagStr());
611  // remove all demand element children of this TAZElement deleteDemandElement this function recursively
612  while (TAZElement->getChildDemandElements().size() > 0) {
613  deleteDemandElement(TAZElement->getChildDemandElements().front(), undoList);
614  }
615  // remove all generic data children of this TAZElement deleteGenericData this function recursively
616  while (TAZElement->getChildGenericDatas().size() > 0) {
617  deleteGenericData(TAZElement->getChildGenericDatas().front(), undoList);
618  }
619  // remove all TAZElement children of this TAZElement calling this function recursively
620  while (TAZElement->getChildTAZElements().size() > 0) {
621  deleteTAZElement(TAZElement->getChildTAZElements().front(), undoList);
622  }
623  // remove TAZElement
624  undoList->add(new GNEChange_TAZElement(TAZElement, false), true);
625  undoList->end();
626 }
627 
628 
629 void
631  // check that default VTypes aren't removed
632  if ((demandElement->getTagProperty().getTag() == SUMO_TAG_VTYPE) && (GNEAttributeCarrier::parse<bool>(demandElement->getAttribute(GNE_ATTR_DEFAULT_VTYPE)))) {
633  throw ProcessError("Trying to delete a default Vehicle Type");
634  } else {
635  // check if currently is being inspected
636  if (myViewNet->isAttributeCarrierInspected(demandElement)) {
638  }
639  undoList->begin(GUIIcon::MODEDELETE, "delete " + demandElement->getTagStr());
640  // remove all child demand elements of this demandElement calling this function recursively
641  while (demandElement->getChildDemandElements().size() > 0) {
642  deleteDemandElement(demandElement->getChildDemandElements().front(), undoList);
643  }
644  // remove all generic data children of this additional deleteGenericData this function recursively
645  while (demandElement->getChildGenericDatas().size() > 0) {
646  deleteGenericData(demandElement->getChildGenericDatas().front(), undoList);
647  }
648  // remove demandElement
649  undoList->add(new GNEChange_DemandElement(demandElement, false), true);
650  undoList->end();
651  }
652 }
653 
654 
655 void
657  undoList->begin(GUIIcon::MODEDELETE, "delete " + dataSet->getTagStr());
658  // make a copy of all generic data children
659  auto copyOfDataIntervalChildren = dataSet->getDataIntervalChildren();
660  // clear all data intervals (this will be delete also the dataSet)
661  for (const auto& dataInterval : copyOfDataIntervalChildren) {
662  deleteDataInterval(dataInterval.second, undoList);
663  }
664  undoList->end();
665 }
666 
667 
668 void
670  undoList->begin(GUIIcon::MODEDELETE, "delete " + dataInterval->getTagStr());
671  // make a copy of all generic data children
672  auto copyOfGenericDataChildren = dataInterval->getGenericDataChildren();
673  // clear all generic datas (this will be delete also the data intervals)
674  for (const auto& genericData : copyOfGenericDataChildren) {
675  deleteGenericData(genericData, undoList);
676  }
677  undoList->end();
678 }
679 
680 
681 void
683  undoList->begin(GUIIcon::MODEDELETE, "delete " + genericData->getTagStr());
684  // remove all child demand elements of this demandElement calling this function recursively
685  while (genericData->getChildDemandElements().size() > 0) {
686  deleteDemandElement(genericData->getChildDemandElements().front(), undoList);
687  }
688  // remove all generic data children of this additional deleteGenericData this function recursively
689  while (genericData->getChildGenericDatas().size() > 0) {
690  deleteGenericData(genericData->getChildGenericDatas().front(), undoList);
691  }
692  // get pointer to dataInterval and dataSet
693  GNEDataInterval* dataInterval = genericData->getDataIntervalParent();
694  GNEDataSet* dataSet = dataInterval->getDataSetParent();
695  // remove generic data
696  undoList->add(new GNEChange_GenericData(genericData, false), true);
697  // check if data interval is empty
698  if (dataInterval->getGenericDataChildren().empty()) {
699  // remove data interval
700  undoList->add(new GNEChange_DataInterval(genericData->getDataIntervalParent(), false), true);
701  // now check if data set is empty
702  if (dataSet->getDataIntervalChildren().empty()) {
703  // remove data set
704  undoList->add(new GNEChange_DataSet(genericData->getDataIntervalParent()->getDataSetParent(), false), true);
705  }
706  }
707  undoList->end();
708 }
709 
710 
711 void
712 GNENet::duplicateLane(GNELane* lane, GNEUndoList* undoList, bool recomputeConnections) {
713  undoList->begin(GUIIcon::LANE, "duplicate " + toString(SUMO_TAG_LANE));
714  GNEEdge* edge = lane->getParentEdge();
715  const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
716  if (recomputeConnections) {
717  edge->getFromJunction()->setLogicValid(false, undoList);
718  edge->getToJunction()->setLogicValid(false, undoList);
719  }
720  GNELane* newLane = new GNELane(edge, lane->getIndex());
721  undoList->add(new GNEChange_Lane(edge, newLane, laneAttrs, true, recomputeConnections), true);
723  undoList->end();
724 }
725 
726 
727 bool
729  bool addRestriction = true;
730  if (vclass == SVC_PEDESTRIAN) {
731  GNEEdge* edge = lane->getParentEdge();
732  for (const auto& edgeLane : edge->getLanes()) {
733  if (edgeLane->isRestricted(SVC_PEDESTRIAN)) {
734  // prevent adding a 2nd sidewalk
735  addRestriction = false;
736  } else {
737  // ensure that the sidewalk is used exclusively
738  const SVCPermissions allOldWithoutPeds = edge->getNBEdge()->getPermissions(edgeLane->getIndex()) & ~SVC_PEDESTRIAN;
739  edgeLane->setAttribute(SUMO_ATTR_ALLOW, getVehicleClassNames(allOldWithoutPeds), undoList);
740  }
741  }
742  }
743  // restrict the lane
744  if (addRestriction) {
745  double width;
746  if (vclass == SVC_PEDESTRIAN) {
747  width = OptionsCont::getOptions().getFloat("default.sidewalk-width");
748  } else if (vclass == SVC_BICYCLE) {
749  width = OptionsCont::getOptions().getFloat("default.bikelane-width");
750  } else {
751  width = OptionsCont::getOptions().getFloat("default.lanewidth");
752  }
753  lane->setAttribute(SUMO_ATTR_ALLOW, toString(vclass), undoList);
754  lane->setAttribute(SUMO_ATTR_WIDTH, toString(width), undoList);
755  return true;
756  } else {
757  return false;
758  }
759 }
760 
761 
762 bool
763 GNENet::addRestrictedLane(SUMOVehicleClass vclass, GNEEdge* edge, int index, GNEUndoList* undoList) {
764  // First check that edge don't have a restricted lane of the given vclass
765  for (const auto& lane : edge->getLanes()) {
766  if (lane->isRestricted(vclass)) {
767  return false;
768  }
769  }
770  // check that index is correct (index == size adds to the left of the leftmost lane)
771  const int numLanes = (int)edge->getLanes().size();
772  if (index > numLanes) {
773  return false;
774  }
775  if (index < 0) {
776  // guess index from vclass
777  if (vclass == SVC_PEDESTRIAN) {
778  index = 0;
779  } else if (vclass == SVC_BICYCLE) {
780  // add bikelanes to the left of an existing sidewalk
781  index = edge->getLanes()[0]->isRestricted(SVC_PEDESTRIAN) ? 1 : 0;
782  } else if (vclass == SVC_BUS) {
783  // add greenVerge to the left of an existing sidewalk or bikeLane
784  // add busLane to the left of an existing sidewalk, bikeLane or greenVerge
785  index = 0;
786  while (index < numLanes && (edge->getNBEdge()->getPermissions(index) & ~(SVC_PEDESTRIAN | SVC_BICYCLE)) == 0) {
787  index++;
788  }
789  }
790  }
791  // duplicate selected lane
792  duplicateLane(edge->getLanes().at(MIN2(index, numLanes - 1)), undoList, true);
793  // transform the created lane
794  return restrictLane(vclass, edge->getLanes().at(index), undoList);
795 }
796 
797 
798 bool
799 GNENet::addGreenVergeLane(GNEEdge* edge, int index, GNEUndoList* undoList) {
800  // check that index is correct (index == size adds to the left of the leftmost lane)
801  const int numLanes = (int)edge->getLanes().size();
802  if (index > numLanes) {
803  index = numLanes;
804  }
805  if (index < 0) {
806  index = 0;
807  }
808  // duplicate selected lane
809  duplicateLane(edge->getLanes().at(MIN2(index, numLanes - 1)), undoList, true);
810  // transform the created lane
811  return restrictLane(SVC_IGNORING, edge->getLanes().at(index), undoList);
812 }
813 
814 
815 bool
817  // iterate over lanes of edge
818  for (const auto& lane : edge->getLanes()) {
819  if (lane->isRestricted(vclass)) {
820  // Delete lane
821  deleteLane(lane, undoList, true);
822  return true;
823  }
824  }
825  return false;
826 }
827 
828 
830 GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
831  // begin undo list
832  undoList->begin(GUIIcon::EDGE, "split " + toString(SUMO_TAG_EDGE));
833  // check if we have to create a new edge
834  if (newJunction == nullptr) {
835  newJunction = createJunction(pos, undoList);
836  }
837  // obtain edge geometry and split position
838  const PositionVector& oldEdgeGeometry = edge->getNBEdge()->getGeometry();
839  const double edgeSplitPosition = oldEdgeGeometry.nearest_offset_to_point2D(pos, false);
840  // obtain lane geometry and split position (needed for adjust additional and demand childs)
841  const PositionVector& oldLaneGeometry = edge->getLanes().front()->getLaneShape();
842  const double laneSplitPosition = oldLaneGeometry.nearest_offset_to_point2D(pos, false);
843  // split edge geometry in two new geometries using edgeSplitPosition
844  std::pair<PositionVector, PositionVector> newGeoms = oldEdgeGeometry.splitAt(edgeSplitPosition);
845  const double oldLength = oldEdgeGeometry.length();
846  const double relativeLength1 = oldLength != 0 ? newGeoms.first.length() / oldLength : 1;
847  const double relativeLength2 = oldLength != 0 ? newGeoms.second.length() / oldLength : 1;
848  // get shape end
849  const std::string shapeEnd = edge->getAttribute(GNE_ATTR_SHAPE_END);
850  // figure out the new name
851  int posBase = 0;
852  // set baseName
853  std::string baseName = edge->getMicrosimID();
854  if (edge->wasSplit()) {
855  const std::string::size_type sep_index = baseName.rfind('.');
856  // edge may have been renamed in between
857  if (sep_index != std::string::npos) {
858  std::string posString = baseName.substr(sep_index + 1);
859  if (GNEAttributeCarrier::canParse<int>(posString.c_str())) {
860  ;
861  posBase = GNEAttributeCarrier::parse<int>(posString.c_str());
862  baseName = baseName.substr(0, sep_index); // includes the .
863  }
864  }
865  }
866  baseName += '.';
867  // create a new edge from the new junction to the previous destination
868  GNEEdge* secondPart = createEdge(newJunction, edge->getToJunction(), edge,
869  undoList, baseName + toString(posBase + (int)edgeSplitPosition), true, false, false);
870  // fix connections from the split edge (must happen before changing SUMO_ATTR_TO)
871  edge->getToJunction()->replaceIncomingConnections(edge, secondPart, undoList);
872  // remove affected crossings from junction (must happen before changing SUMO_ATTR_TO)
873  std::vector<NBNode::Crossing> affectedCrossings;
874  for (GNECrossing* crossing : edge->getToJunction()->getGNECrossings()) {
875  if (crossing->checkEdgeBelong(edge)) {
876  NBNode::Crossing nbC = *crossing->getNBCrossing();
877  undoList->add(new GNEChange_Crossing(edge->getToJunction(), nbC, false), true);
878  EdgeVector newEdges;
879  for (NBEdge* nbEdge : nbC.edges) {
880  if (nbEdge == edge->getNBEdge()) {
881  newEdges.push_back(secondPart->getNBEdge());
882  } else {
883  newEdges.push_back(nbEdge);
884  }
885  }
886  nbC.edges = newEdges;
887  affectedCrossings.push_back(nbC);
888  }
889  }
890  // modify the edge so that it ends at the new junction (and all incoming connections are preserved
891  undoList->changeAttribute(new GNEChange_Attribute(edge, SUMO_ATTR_TO, newJunction->getID()));
892  // set first part of geometry
893  newGeoms.first.pop_back();
894  newGeoms.first.erase(newGeoms.first.begin());
895  edge->setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
896  edge->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);
897  // set second part of geometry
898  secondPart->setAttribute(GNE_ATTR_SHAPE_END, shapeEnd, undoList);
899  newGeoms.second.pop_back();
900  newGeoms.second.erase(newGeoms.second.begin());
901  secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
902  // fix custom length
903  if (edge->getNBEdge()->hasLoadedLength()) {
904  // split in proportion to geometry lengths
905  const double loadedLength = edge->getNBEdge()->getLoadedLength();
906  edge->setAttribute(SUMO_ATTR_LENGTH, toString(relativeLength1 * loadedLength), undoList);
907  secondPart->setAttribute(SUMO_ATTR_LENGTH, toString(relativeLength2 * loadedLength), undoList);
908  }
909  // reconnect across the split
910  for (int i = 0; i < (int)edge->getLanes().size(); ++i) {
911  undoList->add(new GNEChange_Connection(edge, NBEdge::Connection(i, secondPart->getNBEdge(), i), false, true), true);
912  }
913  // re-add modified crossings
914  for (const auto& nbC : affectedCrossings) {
915  undoList->add(new GNEChange_Crossing(secondPart->getToJunction(), nbC, true), true);
916  }
917  // Split geometry of all child additional
918  auto childAdditionals = edge->getChildAdditionals();
919  for (const auto& additional : childAdditionals) {
920  additional->splitEdgeGeometry(edgeSplitPosition, edge, secondPart, undoList);
921  }
922  // Split geometry of all child lane additional
923  for (int i = 0; i < (int)edge->getLanes().size(); i++) {
924  for (const auto& additional : edge->getLanes().at(i)->getChildAdditionals()) {
925  additional->splitEdgeGeometry(laneSplitPosition, edge->getLanes().at(i), secondPart->getLanes().at(i), undoList);
926  }
927  }
928  // Split geometry of all child demand elements
929  auto childDemandElements = edge->getChildDemandElements();
930  for (const auto& demandElement : childDemandElements) {
931  demandElement->splitEdgeGeometry(edgeSplitPosition, edge, secondPart, undoList);
932  }
933  // Split geometry of all child lane demand elements
934  for (int i = 0; i < (int)edge->getLanes().size(); i++) {
935  for (const auto& demandElement : edge->getLanes().at(i)->getChildDemandElements()) {
936  demandElement->splitEdgeGeometry(laneSplitPosition, edge->getLanes().at(i), secondPart->getLanes().at(i), undoList);
937  }
938  }
939  // finish undo list
940  undoList->end();
941  // return new junction
942  return newJunction;
943 }
944 
945 
946 void
947 GNENet::splitEdgesBidi(GNEEdge* edge, GNEEdge* oppositeEdge, const Position& pos, GNEUndoList* undoList) {
948  GNEJunction* newJunction = nullptr;
949  undoList->begin(GUIIcon::EDGE, "split " + toString(SUMO_TAG_EDGE) + "s");
950  // split edge and save created junction
951  newJunction = splitEdge(edge, pos, undoList, newJunction);
952  // split second edge
953  splitEdge(oppositeEdge, pos, undoList, newJunction);
954  if (edge->getLanes().back()->getAttribute(GNE_ATTR_OPPOSITE) != "") {
955  // restore opposit lane information
956  for (const auto& nbEdge : newJunction->getNBNode()->getEdges()) {
957  GNEEdge* e = myAttributeCarriers->retrieveEdge(nbEdge->getID());
958  // store old attribute before it's changed by guess opposite
959  e->getLanes().back()->setAttribute(GNE_ATTR_OPPOSITE, "", undoList);
960  if (nbEdge->guessOpposite(true)) {
961  e->getLanes().back()->setAttribute(GNE_ATTR_OPPOSITE, nbEdge->getLanes().back().oppositeID, undoList);
962  }
963  }
964  }
965  undoList->end();
966 }
967 
968 
969 void
971  undoList->begin(GUIIcon::EDGE, "reverse " + toString(SUMO_TAG_EDGE));
972  deleteEdge(edge, undoList, false); // still exists. we delete it so we can reuse the name in case of resplit
973  GNEEdge* reversed = createEdge(edge->getToJunction(), edge->getFromJunction(), edge, undoList, edge->getID(), false, true);
974  assert(reversed != 0);
975  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
978  undoList->end();
979 }
980 
981 
982 GNEEdge*
984  undoList->begin(GUIIcon::EDGE, "add reversed " + toString(SUMO_TAG_EDGE));
985  GNEEdge* reversed = nullptr;
987  // for rail edges, we assume bi-directional tracks are wanted
988  reversed = createEdge(edge->getToJunction(), edge->getFromJunction(), edge, undoList, "-" + edge->getID(), false, true);
989  assert(reversed != 0);
990  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
993  } else {
994  // if the edge is centered it should probably connect somewhere else
995  // make it easy to move and reconnect it
996  PositionVector orig = edge->getNBEdge()->getGeometry();
997  PositionVector origInner = edge->getNBEdge()->getInnerGeometry();
998  const double tentativeShift = edge->getNBEdge()->getTotalWidth() + 2;
999  orig.move2side(-tentativeShift);
1000  origInner.move2side(-tentativeShift);
1001  GNEJunction* src = createJunction(orig.back(), undoList);
1002  GNEJunction* dest = createJunction(orig.front(), undoList);
1003  reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true);
1004  assert(reversed != 0);
1005  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
1006  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
1007  // select the new edge and its nodes
1008  reversed->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1009  src->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1010  dest->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1011  }
1012  undoList->end();
1013  return reversed;
1014 }
1015 
1016 
1017 void
1019  undoList->begin(GUIIcon::JUNCTION, "merge " + toString(SUMO_TAG_JUNCTION) + "s");
1020  // place moved junction in the same position of target junction
1021  moved->setAttribute(SUMO_ATTR_POSITION, target->getAttribute(SUMO_ATTR_POSITION), undoList);
1022  // deleting edges changes in the underlying EdgeVector so we have to make a copy
1023  const EdgeVector incomingNBEdges = moved->getNBNode()->getIncomingEdges();
1024  for (const auto& incomingNBEdge : incomingNBEdges) {
1025  // delete edges between the merged junctions
1026  GNEEdge* edge = myAttributeCarriers->getEdges().at(incomingNBEdge->getID());
1027  if (edge->getFromJunction() == target) {
1028  deleteEdge(edge, undoList, false);
1029  } else {
1030  undoList->changeAttribute(new GNEChange_Attribute(edge, SUMO_ATTR_TO, target->getID()));
1031  }
1032  }
1033  // deleting edges changes in the underlying EdgeVector so we have to make a copy
1034  const EdgeVector outgoingNBEdges = moved->getNBNode()->getOutgoingEdges();
1035  for (const auto& outgoingNBEdge : outgoingNBEdges) {
1036  // delete edges between the merged junctions
1037  GNEEdge* edge = myAttributeCarriers->getEdges().at(outgoingNBEdge->getID());
1038  if (edge->getToJunction() == target) {
1039  deleteEdge(edge, undoList, false);
1040  } else {
1041  undoList->changeAttribute(new GNEChange_Attribute(edge, SUMO_ATTR_FROM, target->getID()));
1042  }
1043  }
1044  // deleted moved junction
1045  deleteJunction(moved, undoList);
1046  undoList->end();
1047 }
1048 
1049 
1050 void
1052  for (const EdgeSet& roundabout : myNetBuilder->getEdgeCont().getRoundabouts()) {
1053  for (NBEdge* edge : roundabout) {
1054  if (edge->getFromNode() == junction->getNBNode()) {
1055  undoList->begin(GUIIcon::JUNCTION, "select roundabout");
1056  for (const auto& roundaboutEdge : roundabout) {
1057  GNEEdge* e = myAttributeCarriers->retrieveEdge(roundaboutEdge->getID());
1058  e->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1059  e->getToJunction()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1060  }
1061  undoList->end();
1062  return;
1063  }
1064  }
1065  }
1066 }
1067 
1068 
1069 void
1071  undoList->begin(GUIIcon::JUNCTION, "create roundabout");
1072  junction->getNBNode()->updateSurroundingGeometry();
1073  double radius = junction->getNBNode()->getRadius();
1074  if (radius == NBNode::UNSPECIFIED_RADIUS) {
1075  radius = OptionsCont::getOptions().getFloat("default.junctions.radius");
1076  }
1077  std::vector<GNEEdge*> edges;
1078  // use clockwise sorting
1079  for (const auto& nbEdge : junction->getNBNode()->getEdges()) {
1080  edges.push_back(myAttributeCarriers->retrieveEdge(nbEdge->getID()));
1081  }
1082  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
1083  const double lefthandSign = lefthand ? -1 : 1;
1084  std::vector<GNEJunction*> newJunctions;
1085  GNEEdge* prevOpposite = nullptr;
1086  // split incoming/outgoing edges
1087  for (GNEEdge* edge : edges) {
1088  GNEJunction* newJunction = nullptr;
1089  if (edge == prevOpposite) {
1090  newJunction = newJunctions.back();
1091  }
1092  //std::cout << " edge=" << edge->getID() << " prevOpposite=" << Named::getIDSecure(prevOpposite) << " newJunction=" << Named::getIDSecure(newJunction) << "\n";
1093  prevOpposite = edge->getOppositeEdge();
1094  const double geomLength = edge->getNBEdge()->getGeometry().length2D();
1095  const double splitOffset = (edge->getToJunction() == junction
1096  ? MAX2(POSITION_EPS, geomLength - radius)
1097  : MIN2(geomLength - POSITION_EPS, radius));
1098  Position pos = edge->getNBEdge()->getGeometry().positionAtOffset2D(splitOffset);
1099  newJunction = splitEdge(edge, pos, undoList, newJunction);
1100  if (newJunctions.empty() || newJunction != newJunctions.back()) {
1101  newJunctions.push_back(newJunction);
1102  }
1103  }
1104  Position center = junction->getPositionInView();
1105  deleteJunction(junction, undoList);
1106  // create new edges to connect roundabout junctions (counter-clockwise)
1107  const double resolution = OptionsCont::getOptions().getFloat("opendrive.curve-resolution") * 3;
1108  for (int i = 0; i < (int)newJunctions.size(); i++) {
1109  GNEJunction* from = newJunctions[(i + 1) % newJunctions.size()];
1110  GNEJunction* to = newJunctions[i];
1111  GNEEdge* newEdge = createEdge(from, to, nullptr, undoList);
1112  const double angle1 = center.angleTo2D(from->getPositionInView());
1113  const double angle2 = center.angleTo2D(to->getPositionInView());
1114  // insert geometry points every resolution meters
1115  const double angleDiff = fabs(GeomHelper::angleDiff(angle2, angle1));
1116  // circumference = 2 * M_PI * radius, angularFraction = angleDiff / 2 * M_PI
1117  int numSegments = MAX2(2, (int)ceil(angleDiff * radius / resolution));
1118  PositionVector innerGeom;
1119  for (int j = 1; j < numSegments; j++) {
1120  const double angle = angle1 + lefthandSign * j * angleDiff / numSegments;
1121  innerGeom.push_back(center + Position(cos(angle) * radius, sin(angle) * radius));
1122  }
1123  //std::cout << " newEdge=" << newEdge->getID() << " angle1=" << angle1 << " angle2=" << angle2 << " angleDiff=" << angleDiff
1124  // << " numSegments=" << numSegments << " innerGeom=" << innerGeom << "\n";
1125  newEdge->setAttribute(SUMO_ATTR_SHAPE, toString(innerGeom), undoList);
1126  }
1127  undoList->end();
1128 }
1129 
1130 
1131 bool
1133  // Check that there isn't another junction in the same position as Pos
1134  for (auto i : myAttributeCarriers->getJunctions()) {
1135  if (i.second->getPositionInView() == pos) {
1136  return false;
1137  }
1138  }
1139  return true;
1140 }
1141 
1142 
1143 void
1145  myNetSaved = !value;
1146 }
1147 
1148 
1149 bool
1151  return myNetSaved;
1152 }
1153 
1154 
1155 void
1157  // compute without volatile options and update network
1158  computeAndUpdate(oc, false);
1159  // clear typeContainer
1161  // now update typeContainer with edgeTypes
1162  for (const auto& edgeType : myAttributeCarriers->getEdgeTypes()) {
1163  myNetBuilder->getTypeCont().insertEdgeType(edgeType.first, edgeType.second);
1164  for (int i = 0; i < (int)edgeType.second->getLaneTypes().size(); i++) {
1165  myNetBuilder->getTypeCont().insertLaneType(edgeType.first, i,
1166  edgeType.second->getLaneTypes().at(i)->speed,
1167  edgeType.second->getLaneTypes().at(i)->permissions,
1168  edgeType.second->getLaneTypes().at(i)->width,
1169  edgeType.second->getLaneTypes().at(i)->attrs);
1170  }
1171  }
1172  // write network
1174  myNetSaved = true;
1175 }
1176 
1177 
1178 void
1180  // compute without volatile options
1181  computeAndUpdate(oc, false);
1183 }
1184 
1185 
1186 void
1188  // compute without volatile options
1189  computeAndUpdate(oc, false);
1191 }
1192 
1193 
1194 void
1196  // set view net
1197  myViewNet = viewNet;
1198  // add default vTypes
1200  // update geometry of all lanes (needed for dotted geometry)
1201  for (const auto& edge : myAttributeCarriers->getEdges()) {
1202  for (const auto& lane : edge.second->getLanes()) {
1203  lane->updateGeometry();
1204  }
1205  }
1206 }
1207 
1208 
1209 void
1211  // first check if given object has an associated GUIGlObject
1212  if (AC->getGUIGlObject()) {
1213  // check if object must be inserted in RTREE
1214  if (AC->getTagProperty().isPlacedInRTree()) {
1216  }
1217  }
1218 }
1219 
1220 
1221 void
1223  // first check if given object has an associated GUIGlObject
1224  if (AC->getGUIGlObject()) {
1225  // check if object must be inserted in RTREE
1226  if (AC->getTagProperty().isPlacedInRTree()) {
1228  }
1229  }
1230 }
1231 
1232 
1233 void
1234 GNENet::computeNetwork(GNEApplicationWindow* window, bool force, bool volatileOptions, std::string additionalPath, std::string demandPath, std::string dataPath) {
1235  if (!myNeedRecompute) {
1236  if (force) {
1237  if (volatileOptions) {
1238  window->setStatusBarText("Forced computing junctions with volatile options ...");
1239  } else {
1240  window->setStatusBarText("Forced computing junctions ...");
1241  }
1242  } else {
1243  return;
1244  }
1245  } else {
1246  if (volatileOptions) {
1247  window->setStatusBarText("Computing junctions with volatile options ...");
1248  } else {
1249  window->setStatusBarText("Computing junctions ...");
1250  }
1251  }
1252  // save current number of lanes for every edge if recomputing is with volatile options
1253  if (volatileOptions) {
1254  for (auto it : myAttributeCarriers->getEdges()) {
1255  myEdgesAndNumberOfLanes[it.second->getID()] = (int)it.second->getLanes().size();
1256  }
1257  }
1258  // compute and update
1260  computeAndUpdate(oc, volatileOptions);
1261  // load additionals if was recomputed with volatile options
1262  if (additionalPath != "") {
1263  // Create additional handler
1264  GNEGeneralHandler generalHandler(this, additionalPath, false);
1265  // Run parser
1266  if (!generalHandler.parse()) {
1267  WRITE_MESSAGE("Loading of " + additionalPath + " failed.");
1268  }
1269  // clear myEdgesAndNumberOfLanes after reload additionals
1270  myEdgesAndNumberOfLanes.clear();
1271  }
1272  // load demand elements if was recomputed with volatile options
1273  if (demandPath != "") {
1274  // Create general handler
1275  GNEGeneralHandler handler(this, demandPath, false);
1276  // Run parser
1277  if (!handler.parse()) {
1278  WRITE_MESSAGE("Loading of " + demandPath + " failed.");
1279  }
1280  // clear myEdgesAndNumberOfLanes after reload demandElements
1281  myEdgesAndNumberOfLanes.clear();
1282  }
1283  UNUSED_PARAMETER(dataPath);
1284  window->getApp()->endWaitCursor();
1285  window->setStatusBarText("Finished computing junctions.");
1286 }
1287 
1288 
1289 void
1291  window->setStatusBarText("Computing demand elements ...");
1292  // if we aren't in Demand mode, update path calculator
1296  }
1297  // clear demand paths
1299  // iterate over all demand elements and compute
1300  for (const auto& demandElements : myAttributeCarriers->getDemandElements()) {
1301  for (const auto& demandElement : demandElements.second) {
1302  demandElement->computePathElement();
1303  }
1304  }
1305  window->setStatusBarText("Finished computing demand elements.");
1306 }
1307 
1308 
1309 void
1311  window->setStatusBarText("Computing data elements ...");
1312  // iterate over all demand elements and compute
1313  for (const auto& genericDataTag : myAttributeCarriers->getGenericDatas()) {
1314  for (const auto& genericData : genericDataTag.second) {
1315  genericData->computePathElement();
1316  }
1317  }
1318  window->setStatusBarText("Finished computing data elements.");
1319 }
1320 
1321 
1322 void
1324  // recompute tl-logics
1327  // iterate over traffic lights definitions. Make a copy because invalid
1328  // definitions will be removed (and would otherwise destroy the iterator)
1329  const std::set<NBTrafficLightDefinition*> tlsDefs = junction->getNBNode()->getControllingTLS();
1330  for (auto it : tlsDefs) {
1331  it->setParticipantsInformation();
1332  it->setTLControllingInformation();
1333  tllCont.computeSingleLogic(oc, it);
1334  }
1335 
1336  // @todo compute connections etc...
1337 }
1338 
1339 
1340 void
1342  myNeedRecompute = true;
1343 }
1344 
1345 
1346 bool
1348  return (myNeedRecompute == false);
1349 }
1350 
1351 
1352 FXApp*
1354  return myViewNet->getApp();
1355 }
1356 
1357 
1358 NBNetBuilder*
1360  return myNetBuilder;
1361 }
1362 
1363 
1364 bool
1366  const auto selectedJunctions = myAttributeCarriers->getSelectedJunctions();
1367  if (selectedJunctions.size() < 2) {
1368  return false;
1369  }
1370  EdgeVector allIncoming;
1371  EdgeVector allOutgoing;
1372  std::set<NBNode*, ComparatorIdLess> cluster;
1373  for (auto it : selectedJunctions) {
1374  cluster.insert(it->getNBNode());
1375  const EdgeVector& incoming = it->getNBNode()->getIncomingEdges();
1376  allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end());
1377  const EdgeVector& outgoing = it->getNBNode()->getOutgoingEdges();
1378  allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end());
1379  }
1380  // create new junction
1381  Position pos;
1382  Position oldPos;
1383  bool setTL = false;
1384  std::string id = "cluster";
1385  TrafficLightType type;
1387  myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type, nodeType);
1388  // save position
1389  oldPos = pos;
1390 
1391  // Check that there isn't another junction in the same position as Pos but doesn't belong to cluster
1392  for (auto i : myAttributeCarriers->getJunctions()) {
1393  if ((i.second->getPositionInView() == pos) && (cluster.find(i.second->getNBNode()) == cluster.end())) {
1394  // show warning in gui testing debug mode
1395  WRITE_DEBUG("Opening FXMessageBox 'Join non-selected junction'");
1396  // Ask confirmation to user
1397  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1398  ("Position of joined " + toString(SUMO_TAG_JUNCTION)).c_str(), "%s",
1399  ("There is another unselected " + toString(SUMO_TAG_JUNCTION) + " in the same position of joined " + toString(SUMO_TAG_JUNCTION) +
1400  + ".\nIt will be joined with the other selected " + toString(SUMO_TAG_JUNCTION) + "s. Continue?").c_str());
1401  if (answer != 1) { // 1:yes, 2:no, 4:esc
1402  // write warning if netedit is running in testing mode
1403  if (answer == 2) {
1404  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'No'");
1405  } else if (answer == 4) {
1406  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'ESC'");
1407  }
1408  return false;
1409  } else {
1410  // write warning if netedit is running in testing mode
1411  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'Yes'");
1412  // select conflicted junction an join all again
1413  i.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1414  return joinSelectedJunctions(undoList);
1415  }
1416  }
1417  }
1418 
1419  // use checkJunctionPosition to avoid conflicts with junction in the same position as others
1420  while (checkJunctionPosition(pos) == false) {
1421  pos.setx(pos.x() + 0.1);
1422  pos.sety(pos.y() + 0.1);
1423  }
1424 
1425  // start with the join selected junctions
1426  undoList->begin(GUIIcon::JUNCTION, "Join selected " + toString(SUMO_TAG_JUNCTION) + "s");
1427  GNEJunction* joined = createJunction(pos, undoList);
1428  joined->setAttribute(SUMO_ATTR_TYPE, toString(nodeType), undoList); // i.e. rail crossing
1429  if (setTL) {
1430  joined->setAttribute(SUMO_ATTR_TLTYPE, toString(type), undoList);
1431  }
1432 
1433  // #3128 this is not undone when calling 'undo'
1435 
1436  // first remove all crossing of the involved junctions and edges
1437  // (otherwise edge removal will trigger discarding)
1438  std::vector<NBNode::Crossing> oldCrossings;
1439  for (auto i : selectedJunctions) {
1440  while (i->getGNECrossings().size() > 0) {
1441  GNECrossing* crossing = i->getGNECrossings().front();
1442  oldCrossings.push_back(*crossing->getNBCrossing());
1443  deleteCrossing(crossing, undoList);
1444  }
1445  }
1446 
1447  // preserve old connections
1448  for (auto it : selectedJunctions) {
1449  it->setLogicValid(false, undoList);
1450  }
1451  // remap edges
1452  for (auto it : allIncoming) {
1453  undoList->changeAttribute(new GNEChange_Attribute(myAttributeCarriers->getEdges().at(it->getID()), SUMO_ATTR_TO, joined->getID()));
1454  }
1455 
1456  EdgeSet edgesWithin;
1457  for (auto it : allOutgoing) {
1458  // delete edges within the cluster
1459  GNEEdge* edge = myAttributeCarriers->getEdges().at(it->getID());
1460  if (edge->getToJunction() == joined) {
1461  edgesWithin.insert(it);
1462  deleteEdge(edge, undoList, false);
1463  } else {
1464  undoList->changeAttribute(new GNEChange_Attribute(myAttributeCarriers->getEdges().at(it->getID()), SUMO_ATTR_FROM, joined->getID()));
1465  }
1466  }
1467 
1468  // remap all crossing of the involved junctions and edges
1469  for (auto nbc : oldCrossings) {
1470  bool keep = true;
1471  for (NBEdge* e : nbc.edges) {
1472  if (edgesWithin.count(e) != 0) {
1473  keep = false;
1474  break;
1475  }
1476  };
1477  if (keep) {
1478  undoList->add(new GNEChange_Crossing(joined, nbc.edges, nbc.width,
1479  nbc.priority || joined->getNBNode()->isTLControlled(),
1480  nbc.customTLIndex, nbc.customTLIndex2, nbc.customShape,
1481  false, true), true);
1482  }
1483  }
1484 
1485  // delete original junctions
1486  for (auto it : selectedJunctions) {
1487  deleteJunction(it, undoList);
1488  }
1489  joined->setAttribute(SUMO_ATTR_ID, id, undoList);
1490 
1491 
1492  // check if joined junction had to change their original position to avoid errors
1493  if (pos != oldPos) {
1494  joined->setAttribute(SUMO_ATTR_POSITION, toString(oldPos), undoList);
1495  }
1496  undoList->end();
1497  return true;
1498 }
1499 
1500 
1501 bool
1503  // obtain current net's crossings
1504  std::vector<GNECrossing*> myNetCrossings;
1505  for (auto it : myAttributeCarriers->getJunctions()) {
1506  myNetCrossings.reserve(myNetCrossings.size() + it.second->getGNECrossings().size());
1507  myNetCrossings.insert(myNetCrossings.end(), it.second->getGNECrossings().begin(), it.second->getGNECrossings().end());
1508  }
1509  // obtain invalid crossigns
1510  std::vector<GNECrossing*> myInvalidCrossings;
1511  for (auto i = myNetCrossings.begin(); i != myNetCrossings.end(); i++) {
1512  if ((*i)->getNBCrossing()->valid == false) {
1513  myInvalidCrossings.push_back(*i);
1514  }
1515  }
1516 
1517  if (myInvalidCrossings.empty()) {
1518  // show warning in gui testing debug mode
1519  WRITE_DEBUG("Opening FXMessageBox 'No crossing to remove'");
1520  // open a dialog informing that there isn't crossing to remove
1521  FXMessageBox::warning(getApp(), MBOX_OK,
1522  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1523  ("There is no invalid " + toString(SUMO_TAG_CROSSING) + "s to remove").c_str());
1524  // show warning in gui testing debug mode
1525  WRITE_DEBUG("Closed FXMessageBox 'No crossing to remove' with 'OK'");
1526  } else {
1527  std::string plural = myInvalidCrossings.size() == 1 ? ("") : ("s");
1528  // show warning in gui testing debug mode
1529  WRITE_DEBUG("Opening FXMessageBox 'clear crossings'");
1530  // Ask confirmation to user
1531  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1532  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1533  ("Clear " + toString(SUMO_TAG_CROSSING) + plural + " will be removed. Continue?").c_str());
1534  if (answer != 1) { // 1:yes, 2:no, 4:esc
1535  // write warning if netedit is running in testing mode
1536  if (answer == 2) {
1537  WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'No'");
1538  } else if (answer == 4) {
1539  WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'ESC'");
1540  }
1541  } else {
1542  undoList->begin(GUIIcon::MODEDELETE, "Clean " + toString(SUMO_TAG_CROSSING) + "s");
1543  for (auto i = myInvalidCrossings.begin(); i != myInvalidCrossings.end(); i++) {
1544  deleteCrossing((*i), undoList);
1545  }
1546  undoList->end();
1547  }
1548  }
1549  return 1;
1550 }
1551 
1552 
1553 void
1555  undoList->begin(GUIIcon::MODEDELETE, "Clean " + toString(SUMO_TAG_JUNCTION) + "s");
1556  std::vector<GNEJunction*> toRemove;
1557  for (auto it : myAttributeCarriers->getJunctions()) {
1558  GNEJunction* junction = it.second;
1559  if (junction->getNBNode()->getEdges().size() == 0) {
1560  toRemove.push_back(junction);
1561  }
1562  }
1563  for (auto it : toRemove) {
1564  deleteJunction(it, undoList);
1565  }
1566  undoList->end();
1567 }
1568 
1569 
1570 void
1572  // first declare a vector to save all routes without children
1573  std::vector<GNEDemandElement*> routesWithoutChildren;
1574  routesWithoutChildren.reserve(myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE).size());
1575  // iterate over routes
1576  for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1577  if (route->getChildDemandElements().empty()) {
1578  routesWithoutChildren.push_back(route);
1579  }
1580  }
1581  // finally remove all routesWithoutChildren
1582  if (routesWithoutChildren.size() > 0) {
1583  // begin undo list
1584  undoList->begin(GUIIcon::MODEDELETE, "clean unused routes");
1585  // iterate over routesWithoutChildren
1586  for (const auto& i : routesWithoutChildren) {
1587  // due route doesn't have children, simply call GNEChange_DemandElement
1588  undoList->add(new GNEChange_DemandElement(i, false), true);
1589  }
1590  // end undo list
1591  undoList->end();
1592  }
1593 }
1594 
1595 
1596 void
1598  // first declare a sorted set of sorted route's edges in string format
1599  std::set<std::pair<std::string, GNEDemandElement*> > mySortedRoutes;
1600  // iterate over routes and save it in mySortedRoutes (only if it doesn't have Stop Children)
1601  for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1602  // first check route has stops
1603  bool hasStops = false;
1604  for (const auto& stop : route->getChildDemandElements()) {
1605  if (stop->getTagProperty().isStop()) {
1606  hasStops = true;
1607  }
1608  }
1609  if (!hasStops) {
1610  mySortedRoutes.insert(std::make_pair(GNEAttributeCarrier::parseIDs(route->getParentEdges()), route));
1611  }
1612  }
1613  // now declare a matrix in which organice routes to be merged
1614  std::vector<std::vector<GNEDemandElement*> > routesToMerge;
1615  auto index = mySortedRoutes.begin();
1616  // iterate over mySortedRoutes
1617  for (auto i = mySortedRoutes.begin(); i != mySortedRoutes.end(); i++) {
1618  if (routesToMerge.empty()) {
1619  routesToMerge.push_back({i->second});
1620  } else {
1621  if (index->first == i->first) {
1622  routesToMerge.back().push_back(i->second);
1623  } else {
1624  routesToMerge.push_back({i->second});
1625  index = i;
1626  }
1627  }
1628  }
1629  // now check if there is routes to merge
1630  bool thereIsRoutesToMerge = false;
1631  for (const auto& i : routesToMerge) {
1632  if (i.size() > 1) {
1633  thereIsRoutesToMerge = true;
1634  }
1635  }
1636  // if exist
1637  if (thereIsRoutesToMerge) {
1638  // begin undo list
1639  undoList->begin(GUIIcon::ROUTE, "merge routes");
1640  // iterate over route to edges
1641  for (const auto& i : routesToMerge) {
1642  if (i.size() > 1) {
1643  // iterate over duplicated routes
1644  for (int j = 1; j < (int)i.size(); j++) {
1645  // move all vehicles of every duplicated route
1646  while (i.at(j)->getChildDemandElements().size() > 0) {
1647  i.at(j)->getChildDemandElements().front()->setAttribute(SUMO_ATTR_ROUTE, i.at(0)->getID(), undoList);
1648  }
1649  // finally remove route
1650  undoList->add(new GNEChange_DemandElement(i.at(j), false), true);
1651  }
1652  }
1653  }
1654  // end undo list
1655  undoList->end();
1656  }
1657 }
1658 
1659 
1660 void
1662  // declare personPlan-pos map
1663  std::map<GNEDemandElement*, std::string> personPlanMap;
1664  // iterate over persons
1665  for (const auto& persontag : {
1667  }) {
1668  for (const auto& person : myAttributeCarriers->getDemandElements().at(persontag)) {
1669  if (person->getChildDemandElements().size() > 0) {
1670  // get person plan
1671  GNEDemandElement* personPlan = person->getChildDemandElements().front();
1672  // iterate over all personPlans
1673  while (personPlan) {
1674  // check if personPlan is a stopPerson over edge
1675  if (personPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_EDGE) {
1676  // get previous person plan
1677  GNEDemandElement* previousPersonPlan = person->getPreviousChildDemandElement(personPlan);
1678  // check if arrivalPos of previous personPlan is different of endPos of stopPerson
1679  if (previousPersonPlan && previousPersonPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS) &&
1680  (previousPersonPlan->getAttribute(SUMO_ATTR_ARRIVALPOS) != personPlan->getAttribute(SUMO_ATTR_ENDPOS))) {
1681  personPlanMap[previousPersonPlan] = personPlan->getAttribute(SUMO_ATTR_ENDPOS);
1682  }
1683  }
1684  // go to next person plan
1685  personPlan = person->getNextChildDemandElement(personPlan);
1686  }
1687  }
1688  }
1689  }
1690  // continue if there is personPlanMap to adjust
1691  if (personPlanMap.size() > 0) {
1692  // begin undo list
1693  undoList->begin(GUIIcon::MODEPERSONPLAN, "adjust person plans");
1694  // iterate over invalidDemandElements
1695  for (const auto& personPlan : personPlanMap) {
1696  // set arrivalPos attribute
1697  personPlan.first->setAttribute(SUMO_ATTR_ARRIVALPOS, personPlan.second, undoList);
1698  }
1699  // end undo list
1700  undoList->end();
1701  }
1702 }
1703 
1704 
1705 void
1707  // first declare a vector to save all invalid demand elements
1708  std::vector<GNEDemandElement*> invalidDemandElements;
1709  invalidDemandElements.reserve(myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE).size() +
1712  // iterate over routes
1713  for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1714  if (route->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1715  invalidDemandElements.push_back(route);
1716  }
1717  }
1718  // iterate over flows
1719  for (const auto& flow : myAttributeCarriers->getDemandElements().at(SUMO_TAG_FLOW)) {
1720  if (flow->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1721  invalidDemandElements.push_back(flow);
1722  }
1723  }
1724  // iterate over trip
1725  for (const auto& trip : myAttributeCarriers->getDemandElements().at(SUMO_TAG_TRIP)) {
1726  if (trip->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1727  invalidDemandElements.push_back(trip);
1728  }
1729  }
1730  // continue if there is invalidDemandElements to remove
1731  if (invalidDemandElements.size() > 0) {
1732  // begin undo list
1733  undoList->begin(GUIIcon::MODEDELETE, "remove invalid demand elements");
1734  // iterate over invalidDemandElements
1735  for (const auto& invalidDemandElement : invalidDemandElements) {
1736  // simply call GNEChange_DemandElement
1737  undoList->add(new GNEChange_DemandElement(invalidDemandElement, false), true);
1738  }
1739  // end undo list
1740  undoList->end();
1741  }
1742 }
1743 
1744 void
1746  if (junction->getNBNode()->checkIsRemovable()) {
1747  // start operation
1748  undoList->begin(GUIIcon::JUNCTION, "Replace junction by geometry");
1749  // obtain Edges to join
1750  std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
1751  // clear connections of junction to replace
1752  clearJunctionConnections(junction, undoList);
1753  // iterate over NBEdges to join
1754  for (auto j : toJoin) {
1755  // obtain GNEEdges
1756  GNEEdge* begin = myAttributeCarriers->getEdges().at(j.first->getID());
1757  GNEEdge* continuation = myAttributeCarriers->getEdges().at(j.second->getID());
1758  // remove connections between the edges
1759  std::vector<NBEdge::Connection> connections = begin->getNBEdge()->getConnections();
1760  for (auto con : connections) {
1761  undoList->add(new GNEChange_Connection(begin, con, false, false), true);
1762  }
1763  // fix shape of replaced edge
1764  PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
1765  if (begin->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1766  newShape.push_back(junction->getNBNode()->getPosition());
1767  } else {
1768  newShape.push_back(begin->getNBEdge()->getGeometry()[-1]);
1769  }
1770  if (continuation->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1771  newShape.push_back_noDoublePos(junction->getNBNode()->getPosition());
1772  } else {
1773  newShape.push_back_noDoublePos(continuation->getNBEdge()->getGeometry()[0]);
1774  }
1775  // replace incoming edge
1776  replaceIncomingEdge(continuation, begin, undoList);
1777 
1778  newShape.append(continuation->getNBEdge()->getInnerGeometry());
1779  begin->setAttribute(GNE_ATTR_SHAPE_END, continuation->getAttribute(GNE_ATTR_SHAPE_END), undoList);
1780  begin->setAttribute(SUMO_ATTR_ENDOFFSET, continuation->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
1781  begin->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
1782  begin->getNBEdge()->resetNodeBorder(begin->getNBEdge()->getToNode());
1783  // fix loaded lengths
1784  if (begin->getNBEdge()->hasLoadedLength() || continuation->getNBEdge()->hasLoadedLength()) {
1785  begin->setAttribute(SUMO_ATTR_LENGTH, toString(begin->getNBEdge()->getLoadedLength() + continuation->getNBEdge()->getLoadedLength()), undoList);
1786  }
1787  }
1788  //delete replaced junction
1789  deleteJunction(junction, undoList);
1790  // finish operation
1791  undoList->end();
1792  } else {
1793  throw ProcessError("Junction isn't removable");
1794  }
1795 }
1796 
1797 
1798 void
1799 GNENet::splitJunction(GNEJunction* junction, bool reconnect, GNEUndoList* undoList) {
1800  std::vector<std::pair<Position, std::string> > endpoints = junction->getNBNode()->getEndPoints();
1801  if (endpoints.size() < 2) {
1802  return;
1803  }
1804  // start operation
1805  undoList->begin(GUIIcon::JUNCTION, "Split junction");
1806  // record connections
1807  std::map<GNEEdge*, std::vector<NBEdge::Connection>> straightConnections;
1808  for (GNEEdge* e : junction->getGNEIncomingEdges()) {
1809  for (const auto& c : e->getNBEdge()->getConnections()) {
1810  if (c.fromLane >= 0 && junction->getNBNode()->getDirection(e->getNBEdge(), c.toEdge) == LinkDirection::STRAIGHT) {
1811  straightConnections[e].push_back(c);
1812  }
1813  };
1814  }
1815  //std::cout << "split junction at endpoints:\n";
1816 
1817  junction->setLogicValid(false, undoList);
1818  for (const auto& pair : endpoints) {
1819  const Position& pos = pair.first;
1820  const std::string& origID = pair.second;
1821  GNEJunction* newJunction = createJunction(pos, undoList);
1822  std::string newID = origID != "" ? origID : newJunction->getID();
1823  // make a copy because the original vectors are modified during iteration
1824  const std::vector<GNEEdge*> incoming = junction->getGNEIncomingEdges();
1825  const std::vector<GNEEdge*> outgoing = junction->getGNEOutgoingEdges();
1826  //std::cout << " checkEndpoint " << pair.first << " " << pair.second << " newID=" << newID << "\n";
1827  for (GNEEdge* e : incoming) {
1828  //std::cout << " incoming " << e->getID() << " pos=" << pos << " origTo=" << e->getNBEdge()->getParameter("origTo") << " newID=" << newID << "\n";
1829  if (e->getNBEdge()->getGeometry().back().almostSame(pos) || e->getNBEdge()->getParameter("origTo") == newID) {
1830  //std::cout << " match\n";
1831  undoList->changeAttribute(new GNEChange_Attribute(e, SUMO_ATTR_TO, newJunction->getID()));
1832  }
1833  }
1834  for (GNEEdge* e : outgoing) {
1835  //std::cout << " outgoing " << e->getID() << " pos=" << pos << " origFrom=" << e->getNBEdge()->getParameter("origFrom") << " newID=" << newID << "\n";
1836  if (e->getNBEdge()->getGeometry().front().almostSame(pos) || e->getNBEdge()->getParameter("origFrom") == newID) {
1837  //std::cout << " match\n";
1838  undoList->changeAttribute(new GNEChange_Attribute(e, SUMO_ATTR_FROM, newJunction->getID()));
1839  }
1840  }
1841  if (newID != newJunction->getID()) {
1842  if (newJunction->isValid(SUMO_ATTR_ID, newID)) {
1843  undoList->changeAttribute(new GNEChange_Attribute(newJunction, SUMO_ATTR_ID, newID));
1844  } else {
1845  WRITE_WARNING("Could not rename split node to '" + newID + "'");
1846  }
1847  }
1848  }
1849  // recreate edges from straightConnections
1850  if (reconnect) {
1851  for (const auto& item : straightConnections) {
1852  GNEEdge* in = item.first;
1853  std::map<NBEdge*, GNEEdge*> newEdges;
1854  for (auto& c : item.second) {
1855  GNEEdge* out = myAttributeCarriers->retrieveEdge(c.toEdge->getID());
1856  GNEEdge* newEdge = nullptr;
1857  if (in->getToJunction() == out->getFromJunction()) {
1858  continue;
1859  }
1860  if (newEdges.count(c.toEdge) == 0) {
1861  newEdge = createEdge(in->getToJunction(), out->getFromJunction(), in, undoList);
1862  newEdges[c.toEdge] = newEdge;
1863  newEdge->setAttribute(SUMO_ATTR_NUMLANES, "1", undoList);
1864  } else {
1865  newEdge = newEdges[c.toEdge];
1866  duplicateLane(newEdge->getLanes().back(), undoList, true);
1867  }
1868  // copy permissions
1869  newEdge->getLanes().back()->setAttribute(SUMO_ATTR_ALLOW,
1870  in->getLanes()[c.fromLane]-> getAttribute(SUMO_ATTR_ALLOW), undoList);
1871  }
1872  }
1873  }
1874 
1875  deleteJunction(junction, undoList);
1876  // finish operation
1877  undoList->end();
1878 }
1879 
1880 
1881 
1882 void
1884  undoList->begin(GUIIcon::MODEDELETE, "clear junction connections");
1885  std::vector<GNEConnection*> connections = junction->getGNEConnections();
1886  // Iterate over all connections and clear it
1887  for (auto i : connections) {
1888  deleteConnection(i, undoList);
1889  }
1890  undoList->end();
1891 }
1892 
1893 
1894 void
1896  undoList->begin(GUIIcon::CONNECTION, "reset junction connections");
1897  // first clear connections
1898  clearJunctionConnections(junction, undoList);
1899  // invalidate logic to create new connections in the next recomputing
1900  junction->setLogicValid(false, undoList);
1901  undoList->end();
1902 }
1903 
1904 
1905 void
1907  undoList->begin(GUIIcon::MODEADDITIONAL, "clear additional elements");
1908  // clear additionals
1909  for (const auto& additionalMap : myAttributeCarriers->getAdditionals()) {
1910  while (additionalMap.second.size() > 0) {
1911  deleteAdditional(*additionalMap.second.begin(), undoList);
1912  }
1913  }
1914  // clear shapes
1915  for (const auto& shapeMap : myAttributeCarriers->getShapes()) {
1916  while (shapeMap.second.size() > 0) {
1917  deleteShape(*shapeMap.second.begin(), undoList);
1918  }
1919  }
1920  // clear TAZs
1921  for (const auto& TAZMap : myAttributeCarriers->getTAZElements()) {
1922  while (TAZMap.second.size() > 0) {
1923  deleteTAZElement(*TAZMap.second.begin(), undoList);
1924  }
1925  }
1926  undoList->end();
1927 }
1928 
1929 
1930 void
1932  undoList->begin(GUIIcon::MODEDELETE, "clear demand elements");
1933  // clear demand elements
1934  for (const auto& demandElementsMap : myAttributeCarriers->getDemandElements()) {
1935  while (demandElementsMap.second.size() > 0) {
1936  deleteDemandElement(*demandElementsMap.second.begin(), undoList);
1937  }
1938  }
1939  undoList->end();
1940 }
1941 
1942 
1943 void
1945  undoList->begin(GUIIcon::MODEDELETE, "clear data elements");
1946  // clear data sets
1947  for (const auto& dataSet : myAttributeCarriers->getDataSets()) {
1948  deleteDataSet(dataSet, undoList);
1949  }
1950  undoList->end();
1951 }
1952 
1953 
1954 void
1955 GNENet::changeEdgeEndpoints(GNEEdge* edge, const std::string& newSource, const std::string& newDest) {
1956  NBNode* from = myAttributeCarriers->retrieveJunction(newSource)->getNBNode();
1958  edge->getNBEdge()->reinitNodes(from, to);
1959  requireRecompute();
1960 }
1961 
1962 
1963 GNEViewNet*
1965  return myViewNet;
1966 }
1967 
1968 
1971  return myNetBuilder->getTLLogicCont();
1972 }
1973 
1974 
1975 NBEdgeCont&
1977  return myNetBuilder->getEdgeCont();
1978 }
1979 
1980 
1981 void
1983  myExplicitTurnarounds.insert(id);
1984 }
1985 
1986 
1987 void
1989  myExplicitTurnarounds.erase(id);
1990 }
1991 
1992 
1993 void
1995  myAdditionalsSaved = !value;
1996  if (myViewNet != nullptr) {
1997  if (myAdditionalsSaved) {
1999  } else {
2001  }
2002  }
2003 }
2004 
2005 
2006 void
2007 GNENet::saveAdditionals(const std::string& filename) {
2008  // obtain invalid additionals depending of number of their parent lanes
2009  std::vector<GNEAdditional*> invalidSingleLaneAdditionals;
2010  std::vector<GNEAdditional*> invalidMultiLaneAdditionals;
2011  // iterate over additionals and obtain invalids
2012  for (const auto& additionalPair : myAttributeCarriers->getAdditionals()) {
2013  for (const auto& addditional : additionalPair.second) {
2014  // check if has to be fixed
2015  if (addditional->getTagProperty().hasAttribute(SUMO_ATTR_LANE) && !addditional->isAdditionalValid()) {
2016  invalidSingleLaneAdditionals.push_back(addditional);
2017  } else if (addditional->getTagProperty().hasAttribute(SUMO_ATTR_LANES) && !addditional->isAdditionalValid()) {
2018  invalidMultiLaneAdditionals.push_back(addditional);
2019  }
2020  }
2021  }
2022  // if there are invalid StoppingPlaces or detectors, open GNEFixAdditionalElements
2023  if (invalidSingleLaneAdditionals.size() > 0 || invalidMultiLaneAdditionals.size() > 0) {
2024  // 0 -> Canceled Saving, with or whithout selecting invalid stopping places and E2
2025  // 1 -> Invalid stoppingPlaces and E2 fixed, friendlyPos enabled, or saved with invalid positions
2026  GNEFixAdditionalElements fixAdditionalElementsDialog(myViewNet, invalidSingleLaneAdditionals, invalidMultiLaneAdditionals);
2027  if (fixAdditionalElementsDialog.execute() == 0) {
2028  // show debug information
2029  WRITE_DEBUG("Additionals saving aborted");
2030  } else {
2031  saveAdditionalsConfirmed(filename);
2032  // change value of flag
2033  myAdditionalsSaved = true;
2034  // show debug information
2035  WRITE_DEBUG("Additionals saved after dialog");
2036  }
2037  // update view
2039  // set focus again in net
2040  myViewNet->setFocus();
2041  } else {
2042  saveAdditionalsConfirmed(filename);
2043  // change value of flag
2044  myAdditionalsSaved = true;
2045  // show debug information
2046  WRITE_DEBUG("Additionals saved");
2047  }
2048 }
2049 
2050 
2051 bool
2053  return myAdditionalsSaved;
2054 }
2055 
2056 
2057 void
2059  myDemandElementsSaved = !value;
2060  if (myViewNet != nullptr) {
2061  if (myDemandElementsSaved) {
2063  } else {
2065  }
2066  }
2067 }
2068 
2069 
2070 void
2071 GNENet::saveDemandElements(const std::string& filename) {
2072  // first recompute demand elements
2074  // obtain invalid demandElements depending of number of their parent lanes
2075  std::vector<GNEDemandElement*> invalidSingleLaneDemandElements;
2076  // iterate over demandElements and obtain invalids
2077  for (const auto& demandElementSet : myAttributeCarriers->getDemandElements()) {
2078  for (const auto& demandElement : demandElementSet.second) {
2079  // compute before check if demand element is valid
2080  demandElement->computePathElement();
2081  // check if has to be fixed
2082  if (demandElement->isDemandElementValid() != GNEDemandElement::Problem::OK) {
2083  invalidSingleLaneDemandElements.push_back(demandElement);
2084  }
2085  }
2086  }
2087  // if there are invalid demand elements, open GNEFixDemandElements
2088  if (invalidSingleLaneDemandElements.size() > 0) {
2089  // 0 -> Canceled Saving, with or whithout selecting invalid demand elements
2090  // 1 -> Invalid demand elements fixed, friendlyPos enabled, or saved with invalid positions
2091  GNEFixDemandElements fixDemandElementsDialog(myViewNet, invalidSingleLaneDemandElements);
2092  if (fixDemandElementsDialog.execute() == 0) {
2093  // show debug information
2094  WRITE_DEBUG("demand elements saving aborted");
2095  } else {
2096  saveDemandElementsConfirmed(filename);
2097  // change value of flag
2098  myDemandElementsSaved = true;
2099  // show debug information
2100  WRITE_DEBUG("demand elements saved after dialog");
2101  }
2102  // update view
2104  // set focus again in net
2105  myViewNet->setFocus();
2106  } else {
2107  saveDemandElementsConfirmed(filename);
2108  // change value of flag
2109  myDemandElementsSaved = true;
2110  // show debug information
2111  WRITE_DEBUG("demand elements saved");
2112  }
2113 }
2114 
2115 
2116 bool
2118  return myDemandElementsSaved;
2119 }
2120 
2121 
2122 void
2124  myDataElementsSaved = !value;
2125  if (myViewNet != nullptr) {
2126  if (myDataElementsSaved) {
2128  } else {
2130  }
2131  }
2132 }
2133 
2134 
2135 void
2136 GNENet::saveDataElements(const std::string& filename) {
2137  // first recompute data sets
2139  // save data elements
2140  saveDataElementsConfirmed(filename);
2141  // change value of flag
2142  myDataElementsSaved = true;
2143  // show debug information
2144  WRITE_DEBUG("data sets saved");
2145 }
2146 
2147 
2148 bool
2150  return myDataElementsSaved;
2151 }
2152 
2153 
2154 double
2156  double minimumBegin = 0;
2157  // update with first minimum (if exist)
2158  if (myAttributeCarriers->getDataIntervals().size() > 0) {
2159  minimumBegin = (*myAttributeCarriers->getDataIntervals().begin())->getAttributeDouble(SUMO_ATTR_BEGIN);
2160  }
2161  // iterate over interval
2162  for (const auto& interval : myAttributeCarriers->getDataIntervals()) {
2163  if (interval->getAttributeDouble(SUMO_ATTR_BEGIN) < minimumBegin) {
2164  minimumBegin = interval->getAttributeDouble(SUMO_ATTR_BEGIN);
2165  }
2166  }
2167  return minimumBegin;
2168 }
2169 
2170 
2171 double
2173  double maximumEnd = 0;
2174  // update with first maximum (if exist)
2175  if (myAttributeCarriers->getDataIntervals().size() > 0) {
2176  maximumEnd = (*myAttributeCarriers->getDataIntervals().begin())->getAttributeDouble(SUMO_ATTR_END);
2177  }
2178  // iterate over intervals
2179  for (const auto& interval : myAttributeCarriers->getDataIntervals()) {
2180  if (interval->getAttributeDouble(SUMO_ATTR_END) > maximumEnd) {
2181  maximumEnd = interval->getAttributeDouble(SUMO_ATTR_END);
2182  }
2183  }
2184  return maximumEnd;
2185 }
2186 
2187 
2188 void
2189 GNENet::saveAdditionalsConfirmed(const std::string& filename) {
2190  OutputDevice& device = OutputDevice::getDevice(filename);
2191  device.writeXMLHeader("additional", "additional_file.xsd");
2192  // declare map for saving additional sorted by ID
2193  std::vector<std::map<std::string, GNEAdditional*> > sortedAdditionals;
2194  // first write routes with additional children (due route prob reroutes)
2195  std::map<std::string, GNEDemandElement*> sortedRoutes;
2196  for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
2197  if (route->getChildAdditionals().size() > 0) {
2198  sortedRoutes[route->getID()] = route;
2199  }
2200  }
2201  for (const auto& route : sortedRoutes) {
2202  route.second->writeDemandElement(device);
2203  }
2204  // routeProbes
2205  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2206  for (const auto& routeProbe : myAttributeCarriers->getAdditionals().at(SUMO_TAG_ROUTEPROBE)) {
2207  sortedAdditionals.back()[routeProbe->getID()] = routeProbe;
2208  }
2209  // calibrator
2210  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2211  for (const auto& calibrator : myAttributeCarriers->getAdditionals().at(SUMO_TAG_CALIBRATOR)) {
2212  sortedAdditionals.back()[calibrator->getID()] = calibrator;
2213  }
2214  // laneCalibrator
2215  for (const auto& laneCalibrator : myAttributeCarriers->getAdditionals().at(SUMO_TAG_LANECALIBRATOR)) {
2216  sortedAdditionals.back()[laneCalibrator->getID()] = laneCalibrator;
2217  }
2218  // busStop
2219  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2220  for (const auto& busStop : myAttributeCarriers->getAdditionals().at(SUMO_TAG_BUS_STOP)) {
2221  sortedAdditionals.back()[busStop->getID()] = busStop;
2222  }
2223  // trainStop
2224  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2225  for (const auto& trainStop : myAttributeCarriers->getAdditionals().at(SUMO_TAG_TRAIN_STOP)) {
2226  sortedAdditionals.back()[trainStop->getID()] = trainStop;
2227  }
2228  // containerStop
2229  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2230  for (const auto& containerStop : myAttributeCarriers->getAdditionals().at(SUMO_TAG_CONTAINER_STOP)) {
2231  sortedAdditionals.back()[containerStop->getID()] = containerStop;
2232  }
2233  // chargingStation
2234  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2235  for (const auto& chargingStation : myAttributeCarriers->getAdditionals().at(SUMO_TAG_CHARGING_STATION)) {
2236  sortedAdditionals.back()[chargingStation->getID()] = chargingStation;
2237  }
2238  // parkingArea
2239  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2240  for (const auto& parkingArea : myAttributeCarriers->getAdditionals().at(SUMO_TAG_PARKING_AREA)) {
2241  sortedAdditionals.back()[parkingArea->getID()] = parkingArea;
2242  }
2243  // E1
2244  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2245  for (const auto& E1 : myAttributeCarriers->getAdditionals().at(SUMO_TAG_E1DETECTOR)) {
2246  sortedAdditionals.back()[E1->getID()] = E1;
2247  }
2248  // E1Instant
2249  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2250  for (const auto& E1Instant : myAttributeCarriers->getAdditionals().at(SUMO_TAG_INSTANT_INDUCTION_LOOP)) {
2251  sortedAdditionals.back()[E1Instant->getID()] = E1Instant;
2252  }
2253  // E2
2254  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2255  for (const auto& E2 : myAttributeCarriers->getAdditionals().at(SUMO_TAG_E2DETECTOR)) {
2256  sortedAdditionals.back()[E2->getID()] = E2;
2257  }
2258  // E2Multilane
2259  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2260  for (const auto& E2Multilane : myAttributeCarriers->getAdditionals().at(GNE_TAG_E2DETECTOR_MULTILANE)) {
2261  sortedAdditionals.back()[E2Multilane->getID()] = E2Multilane;
2262  }
2263  // E3
2264  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2265  for (const auto& E3 : myAttributeCarriers->getAdditionals().at(SUMO_TAG_E3DETECTOR)) {
2266  sortedAdditionals.back()[E3->getID()] = E3;
2267  }
2268  // rerouters
2269  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2270  for (const auto& rerouter : myAttributeCarriers->getAdditionals().at(SUMO_TAG_REROUTER)) {
2271  sortedAdditionals.back()[rerouter->getID()] = rerouter;
2272  }
2273  // VSS
2274  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2275  for (const auto& VSS : myAttributeCarriers->getAdditionals().at(SUMO_TAG_VSS)) {
2276  sortedAdditionals.back()[VSS->getID()] = VSS;
2277  }
2278  // Vaporizers
2279  sortedAdditionals.push_back(std::map<std::string, GNEAdditional*>());
2280  for (const auto& vaporizer : myAttributeCarriers->getAdditionals().at(SUMO_TAG_VAPORIZER)) {
2281  sortedAdditionals.back()[vaporizer->getID()] = vaporizer;
2282  }
2283  // now write additionals
2284  for (const auto& additionalTag : sortedAdditionals) {
2285  for (const auto& additional : additionalTag) {
2286  additional.second->writeAdditional(device);
2287  }
2288  }
2289  // write TAZs
2290  std::map<std::string, GNETAZElement*> sortedTAZs;
2291  for (const auto& TAZ : myAttributeCarriers->getTAZElements().at(SUMO_TAG_TAZ)) {
2292  sortedTAZs[TAZ->getID()] = TAZ;
2293  }
2294  for (const auto& TAZElement : sortedTAZs) {
2295  TAZElement.second->writeTAZElement(device);
2296  }
2297  // write Polygons
2298  std::map<std::string, GNEShape*> sortedShapes;
2299  for (const auto& poly : myAttributeCarriers->getShapes().at(SUMO_TAG_POLY)) {
2300  sortedShapes[poly->getID()] = poly;
2301  }
2302  for (const auto& shape : sortedShapes) {
2303  shape.second->writeShape(device);
2304  }
2305  sortedShapes.clear();
2306  // write POIs
2307  for (const auto& POI : myAttributeCarriers->getShapes().at(SUMO_TAG_POI)) {
2308  sortedShapes[POI->getID()] = POI;
2309  }
2310  for (const auto& POILane : myAttributeCarriers->getShapes().at(GNE_TAG_POILANE)) {
2311  sortedShapes[POILane->getID()] = POILane;
2312  }
2313  for (const auto& POIGEO : myAttributeCarriers->getShapes().at(GNE_TAG_POIGEO)) {
2314  sortedShapes[POIGEO->getID()] = POIGEO;
2315  }
2316  for (const auto& shape : sortedShapes) {
2317  shape.second->writeShape(device);
2318  }
2319  device.close();
2320 }
2321 
2322 
2323 void
2324 GNENet::saveDemandElementsConfirmed(const std::string& filename) {
2325  OutputDevice& device = OutputDevice::getDevice(filename);
2326  device.writeXMLHeader("routes", "routes_file.xsd", std::map<SumoXMLAttr, std::string>(), false);
2327  // declare map for saving demand elements sorted by ID
2328  std::map<std::string, GNEDemandElement*> sortedDemandElements;
2329  // first write all vTypeDistributions (and their vTypes)
2330  for (const auto& vTypeDistribution : myAttributeCarriers->getDemandElements().at(SUMO_TAG_VTYPE_DISTRIBUTION)) {
2331  sortedDemandElements[vTypeDistribution->getID()] = vTypeDistribution;
2332  }
2333  for (const auto& demandElement : sortedDemandElements) {
2334  demandElement.second->writeDemandElement(device);
2335  }
2336  sortedDemandElements.clear();
2337  // now write all vType without vTypeDistributions
2338  for (const auto& vType : myAttributeCarriers->getDemandElements().at(SUMO_TAG_VTYPE)) {
2339  if (vType->getParentDemandElements().empty()) {
2340  sortedDemandElements[vType->getID()] = vType;
2341  }
2342  }
2343  for (const auto& demandElement : sortedDemandElements) {
2344  demandElement.second->writeDemandElement(device);
2345  }
2346  sortedDemandElements.clear();
2347  // now write all routes (and their associated stops), except routes with additional children (due routeProbReroutes)
2348  for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
2349  if (route->getChildAdditionals().empty()) {
2350  sortedDemandElements[route->getID()] = route;
2351  }
2352  }
2353  for (const auto& demandElement : sortedDemandElements) {
2354  demandElement.second->writeDemandElement(device);
2355  }
2356  // sort vehicles/persons by depart
2357  std::map<double, std::map<std::string, GNEDemandElement*> > vehiclesSortedByDepart;
2358  for (const auto& demandElementTag : myAttributeCarriers->getDemandElements()) {
2359  for (const auto& demandElement : demandElementTag.second) {
2360  if (demandElement->getTagProperty().isVehicle() || demandElement->getTagProperty().isPerson() || demandElement->getTagProperty().isContainer()) {
2361  // save it in myVehiclesSortedByDepart
2362  vehiclesSortedByDepart[GNEAttributeCarrier::parse<double>(demandElement->getBegin())][demandElement->getID()] = demandElement;
2363  }
2364  }
2365  }
2366  // finally write all vehicles, persons and containers sorted by depart time (and their associated stops, personPlans, etc.)
2367  for (const auto& vehicleTag : vehiclesSortedByDepart) {
2368  for (const auto& vehicle : vehicleTag.second) {
2369  vehicle.second->writeDemandElement(device);
2370  }
2371  }
2372  device.close();
2373 }
2374 
2375 
2376 void
2377 GNENet::saveDataElementsConfirmed(const std::string& filename) {
2378  OutputDevice& device = OutputDevice::getDevice(filename);
2379  device.writeXMLHeader("data", "datamode_file.xsd", std::map<SumoXMLAttr, std::string>(), false);
2380  // write all data sets
2381  for (const auto& dataSet : myAttributeCarriers->getDataSets()) {
2382  dataSet->writeDataSet(device);
2383  }
2384  // close device
2385  device.close();
2386 }
2387 
2388 
2389 void
2391  if (myTLSProgramsSaved == true) {
2392  WRITE_DEBUG("TLSPrograms has to be saved");
2393  }
2394  myTLSProgramsSaved = false;
2396 }
2397 
2398 
2399 void
2400 GNENet::saveTLSPrograms(const std::string& filename) {
2401  // open output device
2402  OutputDevice& device = OutputDevice::getDevice(filename);
2403  device.openTag("additionals");
2404  // write traffic lights using NWWriter
2406  device.close();
2407  // change flag to true
2408  myTLSProgramsSaved = true;
2409  // show debug information
2410  WRITE_DEBUG("TLSPrograms saved");
2411 }
2412 
2413 
2414 int
2416  return -1;
2417 }
2418 
2419 
2420 void
2421 GNENet::saveEdgeTypes(const std::string& filename) {
2422  // first clear typeContainer
2424  // now update typeContainer with edgeTypes
2425  for (const auto& edgeType : myAttributeCarriers->getEdgeTypes()) {
2426  myNetBuilder->getTypeCont().insertEdgeType(edgeType.first, edgeType.second);
2427  for (int i = 0; i < (int)edgeType.second->getLaneTypes().size(); i++) {
2428  myNetBuilder->getTypeCont().insertLaneType(edgeType.first, i,
2429  edgeType.second->getLaneTypes().at(i)->speed,
2430  edgeType.second->getLaneTypes().at(i)->permissions,
2431  edgeType.second->getLaneTypes().at(i)->width,
2432  edgeType.second->getLaneTypes().at(i)->attrs);
2433  }
2434  }
2435  // open device
2436  OutputDevice& device = OutputDevice::getDevice(filename);
2437  // open tag
2438  device.openTag(SUMO_TAG_TYPE);
2439  // write edge types
2441  // close tag
2442  device.closeTag();
2443  // close device
2444  device.close();
2445 }
2446 
2447 
2448 void
2450  myUpdateGeometryEnabled = true;
2451 }
2452 
2453 
2454 void
2456  myUpdateGeometryEnabled = false;
2457 }
2458 
2459 
2460 bool
2462  return myUpdateGeometryEnabled;
2463 }
2464 
2465 
2466 void
2468  myUpdateDataEnabled = true;
2469  // update data elements
2470  for (const auto& dataInterval : myAttributeCarriers->getDataIntervals()) {
2471  dataInterval->updateGenericDataIDs();
2472  dataInterval->updateAttributeColors();
2473  }
2474 }
2475 
2476 
2477 void
2479  myUpdateDataEnabled = false;
2480 }
2481 
2482 
2483 bool
2485  return myUpdateDataEnabled;
2486 }
2487 
2488 // ===========================================================================
2489 // private
2490 // ===========================================================================
2491 
2492 void
2494  // init edge types
2495  for (const auto& edgeType : myNetBuilder->getTypeCont()) {
2496  // register edge type
2497  myAttributeCarriers->registerEdgeType(new GNEEdgeType(this, edgeType.first, edgeType.second));
2498  }
2499  // init junctions (by default Crossing and walking areas aren't created)
2500  for (const auto& nodeName : myNetBuilder->getNodeCont().getAllNames()) {
2501  // create and register junction
2503  }
2504  // init edges
2505  for (const auto& edgeName : myNetBuilder->getEdgeCont().getAllNames()) {
2506  // create edge using NBEdge
2507  GNEEdge* edge = new GNEEdge(this, myNetBuilder->getEdgeCont().retrieve(edgeName), false, true);
2508  // register edge
2510  // add manually child references due initJunctionsAndEdges doesn't use undo-redo
2511  edge->getFromJunction()->addChildElement(edge);
2512  edge->getToJunction()->addChildElement(edge);
2513  // check grid
2514  if (myGrid.getWidth() > 10e16 || myGrid.getHeight() > 10e16) {
2515  throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
2516  }
2517  }
2518  // make sure myGrid is initialized even for an empty net
2519  if (myAttributeCarriers->getEdges().size() == 0) {
2520  myGrid.add(Boundary(0, 0, 100, 100));
2521  }
2522  // recalculate all lane2lane connections
2523  for (const auto& edge : myAttributeCarriers->getEdges()) {
2524  for (const auto& lane : edge.second->getLanes()) {
2525  lane->updateGeometry();
2526  }
2527  }
2528  // sort nodes edges so that arrows can be drawn correctly
2530 }
2531 
2532 
2533 void
2535  for (const auto& edge : myAttributeCarriers->getEdges()) {
2536  // remake connections
2537  edge.second->remakeGNEConnections();
2538  // update geometry of connections
2539  for (const auto& connection : edge.second->getGNEConnections()) {
2540  connection->updateGeometry();
2541  }
2542  }
2543 }
2544 
2545 
2546 void
2547 GNENet::computeAndUpdate(OptionsCont& oc, bool volatileOptions) {
2548  // make sure we only add turn arounds to edges which currently exist within the network
2549  std::set<std::string> liveExplicitTurnarounds;
2550  for (const auto& explicitTurnarounds : myExplicitTurnarounds) {
2551  if (myAttributeCarriers->getEdges().count(explicitTurnarounds) > 0) {
2552  liveExplicitTurnarounds.insert(explicitTurnarounds);
2553  }
2554  }
2555  // removes all junctions of grid
2556  WRITE_GLDEBUG("Removing junctions during recomputing");
2557  for (const auto& it : myAttributeCarriers->getJunctions()) {
2558  myGrid.removeAdditionalGLObject(it.second);
2559  }
2560  // remove all edges from grid
2561  WRITE_GLDEBUG("Removing edges during recomputing");
2562  for (const auto& it : myAttributeCarriers->getEdges()) {
2563  myGrid.removeAdditionalGLObject(it.second);
2564  }
2565  // compute using NetBuilder
2566  myNetBuilder->compute(oc, liveExplicitTurnarounds, volatileOptions);
2567  // remap ids if necessary
2568  if (oc.getBool("numerical-ids") || oc.isSet("reserved-ids")) {
2570  }
2571  // update rtree if necessary
2572  if (!oc.getBool("offset.disable-normalization")) {
2573  for (const auto& edge : myAttributeCarriers->getEdges()) {
2574  // refresh edge geometry
2575  edge.second->updateGeometry();
2576  }
2577  }
2578  // Clear current inspected ACs in inspectorFrame if a previous net was loaded
2579  if (myViewNet != nullptr) {
2581  }
2582  // Reset Grid
2583  myGrid.reset();
2584  myGrid.add(GeoConvHelper::getFinal().getConvBoundary());
2585  // if volatile options are true
2586  if (volatileOptions) {
2587  // check that net exist
2588  if (myViewNet == nullptr) {
2589  throw ProcessError("ViewNet doesn't exist");
2590  }
2591  // disable update geometry before clear undo list
2592  myUpdateGeometryEnabled = false;
2593  // destropy Popup
2595  // clear undo list (This will be remove additionals and shapes)
2596  myViewNet->getUndoList()->clear();
2597  // clear all elements (it will also removed from grid)
2604  // enable update geometry again
2605  myUpdateGeometryEnabled = true;
2606  // Write GL debug information
2607  WRITE_GLDEBUG("initJunctionsAndEdges function called in computeAndUpdate(...) due recomputing with volatile options");
2608  // init again junction an edges (Additionals and shapes will be loaded after the end of this function)
2610  // init default vTypes again
2612  } else {
2613  // insert all junctions of grid again
2614  WRITE_GLDEBUG("Add junctions during recomputing after calling myNetBuilder->compute(...)");
2615  for (const auto& junction : myAttributeCarriers->getJunctions()) {
2616  // update centering boundary
2617  junction.second->updateCenteringBoundary(false);
2618  // add junction in grid again
2619  myGrid.addAdditionalGLObject(junction.second);
2620  }
2621  // insert all edges from grid again
2622  WRITE_GLDEBUG("Add edges during recomputing after calling myNetBuilder->compute(...)");
2623  for (const auto& edge : myAttributeCarriers->getEdges()) {
2624  // update centeting boundary
2625  edge.second->updateCenteringBoundary(false);
2626  // add edge in grid again
2627  myGrid.addAdditionalGLObject(edge.second);
2628  }
2629  // remake connections
2630  for (const auto& connection : myAttributeCarriers->getEdges()) {
2631  connection.second->remakeGNEConnections();
2632  }
2633  // iterate over junctions of net
2634  for (const auto& junction : myAttributeCarriers->getJunctions()) {
2635  // undolist may not yet exist but is also not needed when just marking junctions as valid
2636  junction.second->setLogicValid(true, nullptr);
2637  // updated geometry
2638  junction.second->updateGeometryAfterNetbuild();
2639  }
2640  // iterate over all edges of net
2641  for (const auto& edge : myAttributeCarriers->getEdges()) {
2642  // update geometry
2643  edge.second->updateGeometry();
2644  }
2645  }
2646  // net recomputed, then return false;
2647  myNeedRecompute = false;
2648 }
2649 
2650 
2651 void
2652 GNENet::replaceInListAttribute(GNEAttributeCarrier* ac, SumoXMLAttr key, const std::string& which, const std::string& by, GNEUndoList* undoList) {
2653  assert(ac->getTagProperty().getAttributeProperties(key).isList());
2654  std::vector<std::string> values = GNEAttributeCarrier::parse<std::vector<std::string> >(ac->getAttribute(key));
2655  std::vector<std::string> newValues;
2656  for (auto v : values) {
2657  newValues.push_back(v == which ? by : v);
2658  }
2659  ac->setAttribute(key, toString(newValues), undoList);
2660 }
2661 
2662 
2663 /****************************************************************************/
@ GLO_NETWORK
The network - empty.
@ MODEPERSONPLAN
@ MODEADDITIONAL
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:290
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:282
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
#define WRITE_GLDEBUG(msg)
Definition: MsgHandler.h:291
std::set< NBEdge * > EdgeSet
container for unique edges
Definition: NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
TrafficLightType
@ SUMO_TAG_REROUTER
A rerouter.
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_E2DETECTOR
an e2 detector
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_LANECALIBRATOR
A calibrator placed over lane (used in netedit)
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_CONNECTION
connectio between two lanes
@ SUMO_TAG_PARKING_AREA
A parking area.
@ GNE_TAG_E2DETECTOR_MULTILANE
an e2 detector over multiple lanes (placed here due create Additional Frame)
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_INSTANT_INDUCTION_LOOP
An instantenous induction loop.
@ GNE_TAG_POILANE
Point of interest over Lane.
@ SUMO_TAG_E1DETECTOR
an e1 detector
@ SUMO_TAG_PERSON
@ SUMO_TAG_TYPE
type (edge)
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_E3DETECTOR
an e3 detector
@ SUMO_TAG_VSS
A variable speed sign.
@ GNE_TAG_STOPPERSON_EDGE
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
@ STRAIGHT
The link is a straight direction.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ GNE_ATTR_OPPOSITE
neighboring lane, simplified lane attr instead of child element
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ARRIVALPOS
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_NUMLANES
@ SUMO_ATTR_LANES
@ GNE_ATTR_DEFAULT_VTYPE
Flag to check if VType is a default VType.
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_ENDOFFSET
@ GNE_ATTR_SHAPE_END
last coordinate of edge shape
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_ID
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_POSITION
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:74
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
void reset()
Resets the boundary.
Definition: Boundary.cpp:65
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:159
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:153
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:48
The main window of the Netedit.
void enableSaveAdditionalsMenu()
enable save additionals
void setStatusBarText(const std::string &statusBarText)
set text of the statusBar
void disableSaveDemandElementsMenu()
disable save demand elements
void enableSaveDataElementsMenu()
enable save data elements
void disableSaveAdditionalsMenu()
disable save additionals
void enableSaveTLSProgramsMenu()
enable save TLS Programs
void disableSaveDataElementsMenu()
disable save data elements
void enableSaveDemandElementsMenu()
enable save demand elements
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
const std::string & getTagStr() const
get tag assigned to this object in string format
virtual GUIGlObject * getGUIGlObject()=0
get GUIGlObject associated with this AttributeCarrier
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
static std::string parseIDs(const std::vector< T > &ACs)
parses a list of specific Attribute Carriers into a string of IDs
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
virtual std::string getAttribute(SumoXMLAttr key) const =0
bool isList() const
return true if atribute is a list
the function-object for an editing operation (abstract base)
the function-object for an editing operation (abstract base)
Definition: GNEChange.h:64
NBConnection getNBConnection() const
get NBConnection
GNEEdge * getEdgeFrom() const
get the name of the edge the vehicles leave
NBEdge::Connection & getNBEdgeConnection() const
get Edge::Connection
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:42
GNEJunction * getParentJunction() const
get parent Junction
NBNode::Crossing * getNBCrossing() const
get referente to NBode::Crossing
An Element which don't belongs to GNENet but has influency in the simulation.
GNEDataSet * getDataSetParent() const
Returns a pointer to GNEDataSet parent.
const std::vector< GNEGenericData * > & getGenericDataChildren() const
get generic data children
const std::map< const double, GNEDataInterval * > & getDataIntervalChildren() const
get data interval children
Definition: GNEDataSet.cpp:298
An Element which don't belongs to GNENet but has influency in the simulation.
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
virtual std::string getAttribute(SumoXMLAttr key) const =0
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
GNEEdge * getOppositeEdge() const
get opposite edge
Definition: GNEEdge.cpp:384
GNEJunction * getFromJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:77
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:435
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:82
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:782
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:794
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:800
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:894
Dialog for edit rerouters.
Dialog for edit rerouters.
An Element which don't belongs to GNENet but has influency in the simulation.
GNEDataInterval * getDataIntervalParent() const
get data interval parent
void addChildElement(T *element)
add child element
const std::vector< GNETAZElement * > & getChildTAZElements() const
get child TAZElements
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEShape * > & getChildShapes() const
get child shapes
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
const std::vector< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
void clearInspectedAC()
Clear all current inspected ACs.
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
std::string getAttribute(SumoXMLAttr key) const
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
Position getPositionInView() const
Returns position of hierarchical element in view.
void removeConnectionsFrom(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections from the given edge
bool isValid(SumoXMLAttr key, const std::string &value)
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
NBNode * getNBNode() const
Return net build node.
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:797
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNELane.cpp:907
GNEEdge * getParentEdge() const
get arent edge
Definition: GNELane.cpp:113
struct used for saving all attribute carriers of net, in different formats
Definition: GNENetHelper.h:73
const std::map< SumoXMLTag, std::set< GNEGenericData * > > & getGenericDatas() const
get all generic datas
GNEEdgeType * registerEdgeType(GNEEdgeType *edgeType)
registers a edge in GNENet containers
const std::map< SumoXMLTag, std::set< GNEDemandElement * > > & getDemandElements() const
get demand elements
void clearDemandElements()
clear demand elements
GNEEdge * registerEdge(GNEEdge *edge)
registers an edge with GNENet containers
void remapJunctionAndEdgeIds()
remap junction and edge IDs
void clearAdditionals()
clear additionals
GNEJunction * registerJunction(GNEJunction *junction)
registers a junction in GNENet containers
const std::set< GNEDataSet * > & getDataSets() const
get demand elements
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
const std::map< std::string, GNEEdge * > & getEdges() const
map with the ID and pointer to edges of net
void addDefaultVTypes()
add default VTypes
const std::map< SumoXMLTag, std::set< GNETAZElement * > > & getTAZElements() const
get TAZElements
const std::set< GNEDataInterval * > & getDataIntervals() const
get all data intervals of network
std::vector< GNEJunction * > getSelectedJunctions() const
return selected junctions
const std::map< SumoXMLTag, std::set< GNEShape * > > & getShapes() const
get shapes
const std::map< SumoXMLTag, std::set< GNEAdditional * > > & getAdditionals() const
get additionals
void clearTAZElements()
clear TAZElements
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
const std::map< std::string, GNEJunction * > & getJunctions() const
get junctions
const std::map< std::string, GNEEdgeType * > & getEdgeTypes() const
map with the ID and pointer to edgeTypes of net
void clearJunctions()
clear junctions
class for GNEChange_ReplaceEdgeInTLS
Definition: GNENetHelper.h:756
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
void clearAdditionalElements(GNEUndoList *undoList)
clear additionals
Definition: GNENet.cpp:1906
void removeSolitaryJunctions(GNEUndoList *undoList)
removes junctions that have no edges
Definition: GNENet.cpp:1554
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList, bool recomputeConnections)
removes edge
Definition: GNENet.cpp:368
bool joinSelectedJunctions(GNEUndoList *undoList)
join selected junctions
Definition: GNENet.cpp:1365
double getDataSetIntervalMaximumEnd() const
get maximum interval
Definition: GNENet.cpp:2172
void save(OptionsCont &oc)
save the network
Definition: GNENet.cpp:1156
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNENet.cpp:187
void saveDemandElements(const std::string &filename)
save demand element elements of the network
Definition: GNENet.cpp:2071
void deleteLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
removes lane
Definition: GNENet.cpp:502
static const double Z_INITIALIZED
marker for whether the z-boundary is initialized
Definition: GNENet.h:585
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:561
SUMORTree & getGrid()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.cpp:144
GNEViewNet * myViewNet
The net to be notofied of about changes.
Definition: GNENet.h:519
void deleteAdditional(GNEAdditional *additional, GNEUndoList *undoList)
remove additional
Definition: GNENet.cpp:579
bool myDataElementsSaved
Flag to check if data elements has to be saved.
Definition: GNENet.h:555
void disableUpdateGeometry()
disable update geometry of elements after inserting or removing an element in net
Definition: GNENet.cpp:2455
void saveTLSPrograms(const std::string &filename)
save TLS Programs elements of the network
Definition: GNENet.cpp:2400
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1359
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition: GNENet.cpp:1210
void reverseEdge(GNEEdge *edge, GNEUndoList *undoList)
reverse edge
Definition: GNENet.cpp:970
GNEEdge * addReversedEdge(GNEEdge *edge, GNEUndoList *undoList)
add reversed edge
Definition: GNENet.cpp:983
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition: GNENet.cpp:1222
void deleteTAZElement(GNETAZElement *TAZElement, GNEUndoList *undoList)
remove TAZElement
Definition: GNENet.cpp:609
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1970
bool restrictLane(SUMOVehicleClass vclass, GNELane *lane, GNEUndoList *undoList)
transform lane to restricted lane
Definition: GNENet.cpp:728
bool isNetSaved() const
return if net has to be saved
Definition: GNENet.cpp:1150
bool myNetSaved
Flag to check if net has to be saved.
Definition: GNENet.h:543
bool myTLSProgramsSaved
Flag to check if shapes has to be saved.
Definition: GNENet.h:549
void enableUpdateData()
Definition: GNENet.cpp:2467
void requireSaveNet(bool value)
inform that net has to be saved
Definition: GNENet.cpp:1144
GNEJunction * splitEdge(GNEEdge *edge, const Position &pos, GNEUndoList *undoList, GNEJunction *newJunction=0)
split edge at position by inserting a new junction
Definition: GNENet.cpp:830
void setViewNet(GNEViewNet *viewNet)
Set the net to be notified of network changes.
Definition: GNENet.cpp:1195
bool myNeedRecompute
whether the net needs recomputation
Definition: GNENet.h:540
void saveAdditionalsConfirmed(const std::string &filename)
save additionals after confirming invalid objects
Definition: GNENet.cpp:2189
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition: GNENet.cpp:630
void duplicateLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
duplicates lane
Definition: GNENet.cpp:712
const Boundary & getZBoundary() const
Returns the Z boundary (stored in the x() coordinate) values of 0 do not affect the boundary.
Definition: GNENet.cpp:199
const Boundary & getBoundary() const
returns the bounder of the network
Definition: GNENet.cpp:137
void saveEdgeTypes(const std::string &filename)
save edgeTypes elements of the network
Definition: GNENet.cpp:2421
void computeAndUpdate(OptionsCont &oc, bool volatileOptions)
recompute the network and update lane geometries
Definition: GNENet.cpp:2547
SUMORTree myGrid
the rtree which contains all GUIGlObjects (so named for historical reasons)
Definition: GNENet.h:516
void clearDataElements(GNEUndoList *undoList)
clear data elements
Definition: GNENet.cpp:1944
void savePlain(OptionsCont &oc)
save plain xml representation of the network (and nothing else)
Definition: GNENet.cpp:1179
void deleteDataInterval(GNEDataInterval *dataInterval, GNEUndoList *undoList)
remove data interval
Definition: GNENet.cpp:669
void deleteConnection(GNEConnection *connection, GNEUndoList *undoList)
remove connection
Definition: GNENet.cpp:546
void clearDemandElements(GNEUndoList *undoList)
clear demand elements
Definition: GNENet.cpp:1931
void adjustPersonPlans(GNEUndoList *undoList)
adjust person plans
Definition: GNENet.cpp:1661
void requireSaveAdditionals(bool value)
inform that additionals has to be saved
Definition: GNENet.cpp:1994
void cleanInvalidDemandElements(GNEUndoList *undoList)
clean invalid demand elements
Definition: GNENet.cpp:1706
bool myUpdateDataEnabled
Flag to enable or disable update data elements after inserting or removing element in net.
Definition: GNENet.h:561
void cleanUnusedRoutes(GNEUndoList *undoList)
clean unused routes
Definition: GNENet.cpp:1571
NBNetBuilder * myNetBuilder
The internal netbuilder.
Definition: GNENet.h:522
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:1988
void computeJunction(GNEJunction *junction)
trigger recomputation of junction shape and logic param[in] window The window to inform about delay
Definition: GNENet.cpp:1323
void resetJunctionConnections(GNEJunction *junction, GNEUndoList *undoList)
reset junction's connections
Definition: GNENet.cpp:1895
void replaceIncomingEdge(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replaces edge
Definition: GNENet.cpp:436
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNENet.cpp:175
void deleteGenericData(GNEGenericData *genericData, GNEUndoList *undoList)
remove generic data
Definition: GNENet.cpp:682
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:125
void computeNetwork(GNEApplicationWindow *window, bool force=false, bool volatileOptions=false, std::string additionalPath="", std::string demandPath="", std::string dataPath="")
trigger full netbuild computation param[in] window The window to inform about delay param[in] force W...
Definition: GNENet.cpp:1234
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:1955
bool myUpdateGeometryEnabled
Flag to enable or disable update geometry of elements after inserting or removing element in net.
Definition: GNENet.h:558
bool isAdditionalsSaved() const
check if additionals are saved
Definition: GNENet.cpp:2052
void initJunctionsAndEdges()
Init Junctions and edges.
Definition: GNENet.cpp:2493
void splitEdgesBidi(GNEEdge *edge, GNEEdge *oppositeEdge, const Position &pos, GNEUndoList *undoList)
split all edges at position by inserting one new junction
Definition: GNENet.cpp:947
void requireSaveTLSPrograms()
inform that TLS Programs has to be saved
Definition: GNENet.cpp:2390
unsigned int myEdgeIDCounter
Definition: GNENet.h:533
void expandBoundary(const Boundary &newBoundary)
expand boundary
Definition: GNENet.cpp:193
void deleteShape(GNEShape *shape, GNEUndoList *undoList)
remove shape
Definition: GNENet.cpp:600
void disableUpdateData()
disable update data elements after inserting or removing an element in net
Definition: GNENet.cpp:2478
bool removeRestrictedLane(SUMOVehicleClass vclass, GNEEdge *edge, GNEUndoList *undoList)
remove restricted lane
Definition: GNENet.cpp:816
~GNENet()
Destructor.
Definition: GNENet.cpp:113
void mergeJunctions(GNEJunction *moved, GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition: GNENet.cpp:1018
GNEEdge * createEdge(GNEJunction *src, GNEJunction *dest, GNEEdge *edgeTemplate, GNEUndoList *undoList, const std::string &suggestedName="", bool wasSplit=false, bool allowDuplicateGeom=false, bool recomputeConnections=true)
creates a new edge (unless an edge with the same geometry already exists)
Definition: GNENet.cpp:230
std::set< std::string > myExplicitTurnarounds
list of edge ids for which turn-arounds must be added explicitly
Definition: GNENet.h:537
const std::map< std::string, int > & getEdgesAndNumberOfLanes() const
et edges and number of lanes
Definition: GNENet.cpp:149
bool myAdditionalsSaved
Flag to check if additionals has to be saved.
Definition: GNENet.h:546
void addZValueInBoundary(const double z)
add Z in net boundary
Definition: GNENet.cpp:205
bool isUpdateGeometryEnabled() const
check if update geometry after inserting or removing has to be updated
Definition: GNENet.cpp:2461
bool addRestrictedLane(SUMOVehicleClass vclass, GNEEdge *edge, int index, GNEUndoList *undoList)
add restricted lane to edge
Definition: GNENet.cpp:763
bool checkJunctionPosition(const Position &pos)
return true if there are already a Junction in the given position, false in other case
Definition: GNENet.cpp:1132
bool addGreenVergeLane(GNEEdge *edge, int index, GNEUndoList *undoList)
add restricted lane to edge
Definition: GNENet.cpp:799
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNENet.cpp:165
bool isNetRecomputed() const
check if net require recomputing
Definition: GNENet.cpp:1347
bool isUpdateDataEnabled() const
check if update data after inserting or removing has to be updated
Definition: GNENet.cpp:2484
void deleteDataSet(GNEDataSet *dataSet, GNEUndoList *undoList)
remove data set
Definition: GNENet.cpp:656
static void replaceInListAttribute(GNEAttributeCarrier *ac, SumoXMLAttr key, const std::string &which, const std::string &by, GNEUndoList *undoList)
Definition: GNENet.cpp:2652
bool cleanInvalidCrossings(GNEUndoList *undoList)
clear invalid crossings
Definition: GNENet.cpp:1502
void splitJunction(GNEJunction *junction, bool reconnect, GNEUndoList *undoList)
replace the selected junction by a list of junctions for each unique edge endpoint
Definition: GNENet.cpp:1799
void selectRoundabout(GNEJunction *junction, GNEUndoList *undoList)
select all roundabout edges and junctions for the current roundabout
Definition: GNENet.cpp:1051
void joinRoutes(GNEUndoList *undoList)
join routes
Definition: GNENet.cpp:1597
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNENet.cpp:155
void replaceJunctionByGeometry(GNEJunction *junction, GNEUndoList *undoList)
replace the selected junction by geometry node(s) and merge the edges
Definition: GNENet.cpp:1745
void requireSaveDemandElements(bool value)
inform that demand elements has to be saved
Definition: GNENet.cpp:2058
GNEPathManager * myPathManager
Path manager.
Definition: GNENet.h:528
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:131
void createRoundabout(GNEJunction *junction, GNEUndoList *undoList)
transform the given junction into a roundabout
Definition: GNENet.cpp:1070
void requireSaveDataElements(bool value)
inform that data sets has to be saved
Definition: GNENet.cpp:2123
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1341
GNEJunction * createJunction(const Position &pos, GNEUndoList *undoList)
creates a new junction
Definition: GNENet.cpp:214
void saveJoined(OptionsCont &oc)
save log of joined junctions (and nothing else)
Definition: GNENet.cpp:1187
unsigned int myJunctionIDCounter
Definition: GNENet.h:532
std::map< std::string, int > myEdgesAndNumberOfLanes
map with the Edges and their number of lanes
Definition: GNENet.h:588
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration asociated with this GLObject
Definition: GNENet.cpp:181
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:1982
void saveDataElements(const std::string &filename)
save data set elements of the network
Definition: GNENet.cpp:2136
void initGNEConnections()
initialize GNEConnections
Definition: GNENet.cpp:2534
void saveAdditionals(const std::string &filename)
save additional elements of the network
Definition: GNENet.cpp:2007
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition: GNENet.cpp:327
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition: GNENet.cpp:1976
GNENetHelper::AttributeCarriers * myAttributeCarriers
AttributeCarriers of net.
Definition: GNENet.h:525
void computeDataElements(GNEApplicationWindow *window)
compute data elements param[in] window The window to inform about delay
Definition: GNENet.cpp:1310
FXApp * getApp()
get pointer to the main App
Definition: GNENet.cpp:1353
bool isDataElementsSaved() const
check if data sets are saved
Definition: GNENet.cpp:2149
void saveDataElementsConfirmed(const std::string &filename)
save data elements after confirming invalid objects
Definition: GNENet.cpp:2377
bool myDemandElementsSaved
Flag to check if demand elements has to be saved.
Definition: GNENet.h:552
int getNumberOfTLSPrograms() const
get number of TLS Programs
Definition: GNENet.cpp:2415
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1964
void saveDemandElementsConfirmed(const std::string &filename)
save demand elements after confirming invalid objects
Definition: GNENet.cpp:2324
void enableUpdateGeometry()
Definition: GNENet.cpp:2449
void clearJunctionConnections(GNEJunction *junction, GNEUndoList *undoList)
clear junction's connections
Definition: GNENet.cpp:1883
Boundary myZBoundary
the z boundary (stored in the x-coordinate), values of 0 are ignored
Definition: GNENet.h:582
double getDataSetIntervalMinimumBegin() const
get minimum interval
Definition: GNENet.cpp:2155
void computeDemandElements(GNEApplicationWindow *window)
compute demand elements param[in] window The window to inform about delay
Definition: GNENet.cpp:1290
bool isDemandElementsSaved() const
check if demand elements are saved
Definition: GNENet.cpp:2117
const std::string & getID() const
get ID
void updatePathCalculator()
update path calculator (called when SuperModes Demand or Data is selected)
bool isPathCalculatorUpdated() const
check if pathCalculator is updated
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void invalidateJunctionPath(const GNEJunction *junction)
invalidate junction path
void invalidateLanePath(const GNELane *lane)
invalidate lane path
void clearDemandPaths()
clear demand paths
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNETAZElement.h:45
const GNEAttributeProperties & getAttributeProperties(SumoXMLAttr attr) const
get attribute (throw error if doesn't exist)
bool isPlacedInRTree() const
return true if Tag correspond to an element that has has to be placed in RTREE
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
void changeAttribute(GNEChange_Attribute *change)
special method for change attributes, avoid empty changes, always execute
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:513
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
void updateViewNet() const
Mark the entire GNEViewNet to be repainted later.
Definition: GNEViewNet.cpp:372
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
The popup menu of a globject.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used,...
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void setNetObject(GUIGlObject *object)
Sets the given object as the "network" object.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
A window containing a gl-object's parameter.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
void destroyPopup()
destoys the popup
Stores the information about how to visualize structures.
bool parse()
parse
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:179
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:275
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
Definition: NBEdgeCont.cpp:721
The representation of a single edge during network building.
Definition: NBEdge.h:91
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:4022
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:597
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
Definition: NBEdge.cpp:454
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.cpp:942
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:607
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:541
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:515
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:752
void resetNodeBorder(const NBNode *node)
Definition: NBEdge.cpp:731
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
Definition: NBEdge.cpp:3876
std::string getLaneID(int lane) const
get lane ID
Definition: NBEdge.cpp:3693
bool hasDefaultGeometryEndpointAtNode(const NBNode *node) const
Returns whether the geometry is terminated by the node positions This default may be violated by init...
Definition: NBEdge.cpp:617
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:349
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:1006
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:352
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1368
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:598
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
NBTypeCont & getTypeCont()
Returns a reference to the type container.
Definition: NBNetBuilder.h:158
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:148
void compute(OptionsCont &oc, const std::set< std::string > &explicitTurnarounds=std::set< std::string >(), bool mayAddOrRemove=true)
Performs the network building steps.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:153
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:163
A definition of a pedestrian crossing.
Definition: NBNode.h:129
PositionVector customShape
optional customShape for this crossing
Definition: NBNode.h:152
int customTLIndex
the custom traffic light index of this crossing (if controlled)
Definition: NBNode.h:157
int customTLIndex2
Definition: NBNode.h:158
bool priority
whether the pedestrians have priority
Definition: NBNode.h:150
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:136
double width
This crossing's width.
Definition: NBNode.h:142
void registerJoinedCluster(const NodeSet &cluster)
gets all joined clusters (see doc for myClusters2Join)
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:119
std::vector< std::string > getAllNames() const
get all node names
void analyzeCluster(NodeSet cluster, std::string &id, Position &pos, bool &hasTLS, TrafficLightType &type, SumoXMLNodeType &nodeType)
Represents a single node (junction) during network building.
Definition: NBNode.h:66
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
Definition: NBNode.cpp:2221
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition: NBNode.h:208
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3658
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
Definition: NBNode.cpp:2395
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition: NBNode.h:261
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition: NBNode.h:266
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition: NBNode.h:256
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node)
Definition: NBNode.h:324
void updateSurroundingGeometry()
update geometry of node and surrounding edges
Definition: NBNode.cpp:1065
const Position & getPosition() const
Definition: NBNode.h:248
double getRadius() const
Returns the turning radius of this node.
Definition: NBNode.h:278
bool checkIsRemovable() const
check if node is removable
Definition: NBNode.cpp:2319
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:319
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
A container for traffic light definitions and built programs.
bool computeSingleLogic(OptionsCont &oc, NBTrafficLightDefinition *def)
Computes a specific traffic light logic (using by NETEDIT)
void writeEdgeTypes(OutputDevice &into) const
writes all EdgeTypes (and their lanes) as XML
Definition: NBTypeCont.cpp:365
void insertEdgeType(const std::string &id, int numLanes, double maxSpeed, int prio, SVCPermissions permissions, LaneSpreadFunction spreadType, double width, bool oneWayIsDefault, double sidewalkWidth, double bikeLaneWidth, double widthResolution, double maxWidth, double minWidth)
Adds a edgeType into the list.
Definition: NBTypeCont.cpp:194
void clearTypes()
clear types
Definition: NBTypeCont.cpp:166
void insertLaneType(const std::string &edgeTypeID, int index, double maxSpeed, SVCPermissions permissions, double width, const std::set< SumoXMLAttr > &attrs)
Adds a laneType into the list.
Definition: NBTypeCont.cpp:231
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network stored in the given net builder.
Definition: NWFrame.cpp:174
static void writeTrafficLights(OutputDevice &into, const NBTrafficLightLogicCont &tllCont)
writes the traffic light logics to the given device
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into XML-files (nodes, edges, connections, traffic lights)
static void writeJoinedJunctions(const OptionsCont &oc, NBNodeCont &nc)
Writes the joined-juncionts to file.
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
C++ TraCI client API implementation.
Definition: GUI.h:31
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void setx(double x)
set position x
Definition: Position.h:70
double x() const
Returns the x-position.
Definition: Position.h:55
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
Definition: Position.h:262
void sety(double y)
set position y
Definition: Position.h:75
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
double length2D() const
Returns the length.
void append(const PositionVector &v, double sameThreshold=2.0)
double length() const
Returns the length.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
void push_back_noDoublePos(const Position &p)
insert in back a non double position
PositionVector reverse() const
reverse position vector
A RT-tree for efficient storing of SUMO's GL-objects.
Definition: SUMORTree.h:66
void addAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:124
void removeAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition: SUMORTree.h:158
static std::string trim(const std::string s, const std::string &t=" \t\n")
remove leading and trailing whitespace
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:197
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:142