SUMO - Simulation of Urban MObility
GNENet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A visual container for GNE-network-components such as GNEEdge and GNEJunction.
8 // GNE components wrap netbuild-components and supply visualisation and editing
9 // capabilities (adapted from GUINet)
10 //
11 // Workflow (rough draft)
12 // use NILoader to fill
13 // do netedit stuff
14 // call compute to save results
15 //
16 /****************************************************************************/
17 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
18 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
19 /****************************************************************************/
20 //
21 // This file is part of SUMO.
22 // SUMO is free software: you can redistribute it and/or modify
23 // it under the terms of the GNU General Public License as published by
24 // the Free Software Foundation, either version 3 of the License, or
25 // (at your option) any later version.
26 //
27 /****************************************************************************/
28 
29 
30 // ===========================================================================
31 // included modules
32 // ===========================================================================
33 #ifdef _MSC_VER
34 #include <windows_config.h>
35 #else
36 #include <config.h>
37 #endif
38 
39 #include <map>
40 #include <set>
41 #include <vector>
42 
43 #include <netbuild/NBAlgorithms.h>
44 #include <netwrite/NWFrame.h>
45 #include <netwrite/NWWriter_XML.h>
46 #include <utility>
48 #include <utils/common/RGBColor.h>
59 #include <utils/xml/XMLSubSys.h>
60 
61 #include "GNEAdditional.h"
62 #include "GNEAdditionalFrame.h"
63 #include "GNEApplicationWindow.h"
64 #include "GNEChange_Additional.h"
65 #include "GNEChange_Attribute.h"
66 #include "GNEChange_Connection.h"
67 #include "GNEChange_Crossing.h"
68 #include "GNEChange_Edge.h"
69 #include "GNEChange_Junction.h"
70 #include "GNEChange_Lane.h"
71 #include "GNEChange_Selection.h"
72 #include "GNEChange_Poly.h"
73 #include "GNEChange_POI.h"
74 #include "GNEConnection.h"
75 #include "GNECrossing.h"
76 #include "GNEDetector.h"
77 #include "GNEDetectorE2.h"
78 #include "GNEEdge.h"
79 #include "GNEJunction.h"
80 #include "GNEPoly.h"
81 #include "GNEPOI.h"
82 #include "GNELane.h"
83 #include "GNENet.h"
84 #include "GNEStoppingPlace.h"
85 #include "GNEUndoList.h"
86 #include "GNEViewNet.h"
87 #include "GNEViewParent.h"
88 #include "GNERerouter.h"
89 #include "GNEAdditionalHandler.h"
91 
92 
93 FXIMPLEMENT_ABSTRACT(GNENet::GNEChange_ReplaceEdgeInTLS, GNEChange, NULL, 0)
94 
95 // ===========================================================================
96 // static members
97 // ===========================================================================
98 const RGBColor GNENet::selectionColor(0, 0, 204, 255);
99 const RGBColor GNENet::selectedLaneColor(0, 0, 128, 255);
100 const RGBColor GNENet::selectedConnectionColor(0, 0, 100, 255);
101 const RGBColor GNENet::selectedAdditionalColor(0, 0, 150, 255);
102 const double GNENet::Z_INITIALIZED = 1;
103 
104 // ===========================================================================
105 // member method definitions
106 // ===========================================================================
107 GNENet::GNENet(NBNetBuilder* netBuilder) :
109  ShapeContainer(),
110  myViewNet(0),
111  myNetBuilder(netBuilder),
112  myJunctions(),
113  myEdges(),
114  myEdgeIDSupplier("gneE", netBuilder->getEdgeCont().getAllNames()),
115  myJunctionIDSupplier("gneJ", netBuilder->getNodeCont().getAllNames()),
116  myNeedRecompute(true),
117  myAdditionalsSaved(true),
118  myShapesSaved(true) {
119  // set net in gIDStorage
121 
122  // init junction and edges
123  initJunctionsAndEdges();
124 
125  // check Z boundary
126  if (myZBoundary.ymin() != Z_INITIALIZED) {
127  myZBoundary.add(0, 0);
128  }
129 }
130 
131 
133  // Drop Edges
134  for (auto it : myEdges) {
135  it.second->decRef("GNENet::~GNENet");
136  // show extra information for tests
137  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
138  WRITE_WARNING("Deleting unreferenced " + toString(it.second->getTag()) + " '" + it.second->getID() + "' in GNENet destructor");
139  }
140  delete it.second;
141  }
142  // Drop junctions
143  for (auto it : myJunctions) {
144  it.second->decRef("GNENet::~GNENet");
145  // show extra information for tests
146  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
147  WRITE_WARNING("Deleting unreferenced " + toString(it.second->getTag()) + " '" + it.second->getID() + "' in GNENet destructor");
148  }
149  delete it.second;
150  }
151 
152 
153  // show extra information for tests
154  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
155  WRITE_WARNING("Deleting net builder in GNENet destructor");
156  }
157  delete myNetBuilder;
158 }
159 
160 
161 const Boundary&
163  // SUMORTree is also a Boundary
164  return myGrid;
165 }
166 
167 
170  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
171  buildPopupHeader(ret, app);
173  buildPositionCopyEntry(ret, false);
174  return ret;
175 }
176 
177 
180  return 0;
181 }
182 
183 
184 void
186 }
187 
188 
189 Boundary
191  return getBoundary();
192 }
193 
194 
195 const Boundary&
197  return myZBoundary;
198 }
199 
200 
201 SUMORTree&
203  return myGrid;
204 }
205 
206 
207 const SUMORTree&
209  return myGrid;
210 }
211 
212 
215  std::string id = myJunctionIDSupplier.getNext();
216  NBNode* nbn = new NBNode(id, pos);
217  GNEJunction* junction = new GNEJunction(*nbn, this);
218  undoList->add(new GNEChange_Junction(junction, true), true);
219  assert(myJunctions[id]);
220  return junction;
221 }
222 
223 
224 GNEEdge*
226  GNEJunction* src, GNEJunction* dest, GNEEdge* tpl, GNEUndoList* undoList,
227  const std::string& suggestedName,
228  bool wasSplit,
229  bool allowDuplicateGeom) {
230  // prevent duplicate edge (same geometry)
231  const EdgeVector& outgoing = src->getNBNode()->getOutgoingEdges();
232  for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
233  if ((*it)->getToNode() == dest->getNBNode() && (*it)->getGeometry().size() == 2) {
234  if (!allowDuplicateGeom) {
235  return 0;
236  }
237  }
238  }
239 
240  std::string id;
241  if (suggestedName != "" && !retrieveEdge(suggestedName, false)) {
242  id = suggestedName;
243  reserveEdgeID(id);
244  } else {
245  id = myEdgeIDSupplier.getNext();
246  }
247 
248  GNEEdge* edge;
249  if (tpl) {
250  NBEdge* nbeTpl = tpl->getNBEdge();
251  NBEdge* nbe = new NBEdge(id, src->getNBNode(), dest->getNBNode(), nbeTpl);
252  edge = new GNEEdge(*nbe, this, wasSplit);
253  } else {
254  // default if no template is given
255  double defaultSpeed = 50 / 3.6;
256  std::string defaultType = "";
257  int defaultNrLanes = 1;
258  int defaultPriority = 1;
259  double defaultWidth = NBEdge::UNSPECIFIED_WIDTH;
260  double defaultOffset = NBEdge::UNSPECIFIED_OFFSET;
261  NBEdge* nbe = new NBEdge(id, src->getNBNode(), dest->getNBNode(),
262  defaultType, defaultSpeed,
263  defaultNrLanes, defaultPriority,
264  defaultWidth,
265  defaultOffset);
266  edge = new GNEEdge(*nbe, this, wasSplit);
267  }
268  undoList->p_begin("create " + toString(SUMO_TAG_EDGE));
269  undoList->add(new GNEChange_Edge(edge, true), true);
270  src->setLogicValid(false, undoList);
271  dest->setLogicValid(false, undoList);
273  undoList->p_end();
274  assert(myEdges[id]);
275  return edge;
276 }
277 
278 
279 void
281  // we have to delete all incident edges because they cannot exist without that junction
282  // all deletions must be undone/redone together so we start a new command group
283  // @todo if any of those edges are dead-ends should we remove their orphan junctions as well?
284  undoList->p_begin("delete " + toString(SUMO_TAG_JUNCTION));
285 
286  // delete all crossings vinculated with junction
287  while (junction->getGNECrossings().size() > 0) {
288  deleteCrossing(junction->getGNECrossings().front(), undoList);
289  }
290 
291  // find all crossings of neightbour junctions that shares an edge of this junction
292  std::vector<GNECrossing*> crossingsToRemove;
293  std::vector<GNEJunction*> junctionNeighbours = junction->getJunctionNeighbours();
294  for (auto i : junctionNeighbours) {
295  // iterate over crossing of neighbour juntion
296  for (auto j : i->getGNECrossings()) {
297  // if at least one of the edges of junction to remove belongs to a crossing of the neighbour junction, delete it
298  if (j->checkEdgeBelong(junction->getGNEEdges())) {
299  crossingsToRemove.push_back(j);
300  }
301  }
302  }
303 
304  // delete crossings top remove
305  for (auto i : crossingsToRemove) {
306  deleteCrossing(i, undoList);
307  }
308 
309  // deleting edges changes in the underlying EdgeVector so we have to make a copy
310  const EdgeVector incident = junction->getNBNode()->getEdges();
311  for (EdgeVector::const_iterator it = incident.begin(); it != incident.end(); it++) {
312  deleteEdge(myEdges[(*it)->getID()], undoList);
313  }
314 
315  // remove any traffic lights from the traffic light container (avoids lots of warnings)
316  junction->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_PRIORITY), undoList);
317 
318  // save selection status
319  if (gSelected.isSelected(GLO_JUNCTION, junction->getGlID())) {
320  std::set<GUIGlID> deselected;
321  deselected.insert(junction->getGlID());
322  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
323  }
324 
325  // delete edge
326  undoList->add(new GNEChange_Junction(junction, false), true);
327  undoList->p_end();
328 }
329 
330 
331 void
333  undoList->p_begin("delete " + toString(SUMO_TAG_EDGE));
334 
335  // obtain a copy of GNERerouters of edge
336  std::vector<GNERerouter*> rerouters = edge->getGNERerouters();
337 
338  // delete additionals childs of edge
339  std::vector<GNEAdditional*> copyOfEdgeAdditionals = edge->getAdditionalChilds();
340  for (auto i : copyOfEdgeAdditionals) {
341  undoList->add(new GNEChange_Additional(i, false), true);
342  }
343 
344  // delete additionals childs of lane
345  for (auto i : edge->getLanes()) {
346  std::vector<GNEAdditional*> copyOfLaneAdditionals = i->getAdditionalChilds();
347  for (auto j : copyOfLaneAdditionals) {
348  undoList->add(new GNEChange_Additional(j, false), true);
349  }
350  }
351 
352  // remove edge from crossings related with this edge
353  edge->getGNEJunctionSource()->removeEdgeFromCrossings(edge, undoList);
354  edge->getGNEJunctionDestiny()->removeEdgeFromCrossings(edge, undoList);
355 
356  // invalidate junctions
357  edge->getGNEJunctionSource()->setLogicValid(false, undoList);
358  edge->getGNEJunctionDestiny()->setLogicValid(false, undoList);
359 
360  // save selection status
361  if (gSelected.isSelected(GLO_EDGE, edge->getGlID())) {
362  std::set<GUIGlID> deselected;
363  deselected.insert(edge->getGlID());
364  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
365  }
366 
367  // Delete edge
368  undoList->add(new GNEChange_Edge(edge, false), true);
369 
370  // check if after removing there are Rerouters without edge Childs
371  for (auto i : rerouters) {
372  if (i->getEdgeChilds().size() == 0) {
373  undoList->add(new GNEChange_Additional(i, false), true);
374  }
375  }
376  // remove edge requieres always a recompute (due geometry and connections)
378  undoList->p_end();
379 }
380 
381 
382 void
384  undoList->p_begin("replace " + toString(SUMO_TAG_EDGE));
385  undoList->p_add(new GNEChange_Attribute(by, SUMO_ATTR_TO, which->getAttribute(SUMO_ATTR_TO)));
386 
387  // replace in additionals childs of edge
388  std::vector<GNEAdditional*> copyOfEdgeAdditionals = which->getAdditionalChilds();
389  for (auto i : copyOfEdgeAdditionals) {
390  undoList->p_add(new GNEChange_Attribute(i, SUMO_ATTR_EDGE, by->getID()));
391  }
392 
393  // replace in additionals childs of lane
394  for (auto i : which->getLanes()) {
395  std::vector<GNEAdditional*> copyOfLaneAdditionals = i->getAdditionalChilds();
396  for (auto j : copyOfLaneAdditionals) {
397  undoList->p_add(new GNEChange_Attribute(i, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(i->getIndex())));
398  }
399  }
400 
401  // replace in rerouters
402  for (auto rerouter : which->getGNERerouters()) {
403  replaceInListAttribute(rerouter, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
404  }
405 
406  // replace in crossings
407  for (auto crossing : which->getGNEJunctionDestiny()->getGNECrossings()) {
408  // if at least one of the edges of junction to remove belongs to a crossing of the source junction, delete it
409  replaceInListAttribute(crossing, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
410  }
411 
412  // fix connections (make a copy because they will be modified
413  std::vector<NBEdge::Connection> connections = which->getNBEdge()->getConnections();
414  for (auto con : connections) {
415  undoList->add(new GNEChange_Connection(which, con, false, false), true);
416  undoList->add(new GNEChange_Connection(by, con, false, true), true);
417  }
418 
419  // save selection status
420  if (gSelected.isSelected(GLO_EDGE, which->getGlID())) {
421  std::set<GUIGlID> deselected;
422  deselected.insert(which->getGlID());
423  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
424  }
425  undoList->add(new GNEChange_ReplaceEdgeInTLS(getTLLogicCont(), which->getNBEdge(), by->getNBEdge()), true);
426 
427  // Delete edge
428  undoList->add(new GNEChange_Edge(which, false), true);
429 
430  // finish replace edge
431  undoList->p_end();
432 }
433 
434 
435 void
437  GNEEdge* edge = &lane->getParentEdge();
438  if (edge->getNBEdge()->getNumLanes() == 1) {
439  // remove the whole edge instead
440  deleteEdge(edge, undoList);
441  } else {
442  undoList->p_begin("delete " + toString(SUMO_TAG_LANE));
443 
444  // delete additionals childs of lane
445  std::vector<GNEAdditional*> copyOfAdditionals = lane->getAdditionalChilds();
446  for (auto i : copyOfAdditionals) {
447  undoList->add(new GNEChange_Additional(i, false), true);
448  }
449 
450  // invalidate junctions (saving connections)
451  edge->getGNEJunctionSource()->setLogicValid(false, undoList);
452  edge->getGNEJunctionDestiny()->setLogicValid(false, undoList);
453 
454  // save selection status
455  if (gSelected.isSelected(GLO_EDGE, edge->getGlID())) {
456  std::set<GUIGlID> deselected;
457  deselected.insert(edge->getGlID());
458  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
459  }
460 
461  // delete lane
462  const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
463  undoList->add(new GNEChange_Lane(edge, lane, laneAttrs, false), true);
464  if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
465  std::set<GUIGlID> deselected;
466  deselected.insert(lane->getGlID());
467  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
468  }
469 
470  // remove lane requieres always a recompute (due geometry and connections)
472  undoList->p_end();
473  }
474 }
475 
476 
477 void
479  undoList->p_begin("delete " + toString(SUMO_TAG_CONNECTION));
480  // obtain NBConnection to remove
481  NBConnection deleted = connection->getNBConnection();
482  GNEJunction* junctionDestiny = connection->getEdgeFrom()->getGNEJunctionDestiny();
483  junctionDestiny->markAsModified(undoList);
484  // check if GNEConnection was previouslyselected, and if true, unselect it.
485  bool selected = gSelected.isSelected(GLO_CONNECTION, connection->getGlID());
486  if (selected) {
487  gSelected.deselect(connection->getGlID());
488  }
489  undoList->add(new GNEChange_Connection(connection->getEdgeFrom(), connection->getNBEdgeConnection(), selected, false), true);
490  junctionDestiny->invalidateTLS(myViewNet->getUndoList(), deleted);
491  // remove connection requieres always a recompute (due geometry and connections)
493  undoList->p_end();
494 }
495 
496 
497 void
499  undoList->p_begin("delete crossing");
500  // check if GNECrossing was previouslyselected, and if true, unselect it.
501  bool selected = gSelected.isSelected(GLO_CROSSING, crossing->getGlID());
502  if (selected) {
503  gSelected.deselect(crossing->getGlID());
504  }
505  undoList->add(new GNEChange_Crossing(crossing->getParentJunction(), crossing->getNBCrossing()->edges,
506  crossing->getNBCrossing()->width, crossing->getNBCrossing()->priority, selected, false), true);
507  // remove crossing requieres always a recompute (due geometry and connections)
509  undoList->p_end();
510 }
511 
512 
513 void
515  myViewNet->getUndoList()->p_begin("delete " + toString(POI->getTag()));
516  // save selection status
517  if (gSelected.isSelected(GLO_POI, POI->getGlID())) {
518  std::set<GUIGlID> deselected;
519  deselected.insert(POI->getGlID());
520  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
521  }
522  // delete POI
523  myViewNet->getUndoList()->add(new GNEChange_POI(myViewNet->getNet(), POI, false), true);
525 }
526 
527 
528 void
530  myViewNet->getUndoList()->p_begin("delete " + toString(polygon->getTag()));
531  // save selection status
532  if (gSelected.isSelected(GLO_POLYGON, polygon->getGlID())) {
533  std::set<GUIGlID> deselected;
534  deselected.insert(polygon->getGlID());
535  undoList->add(new GNEChange_Selection(this, std::set<GUIGlID>(), deselected, true), true);
536  }
537  // delete Polygon
538  myViewNet->getUndoList()->add(new GNEChange_Poly(myViewNet->getNet(), polygon, false), true);
540 }
541 
542 
543 void
545  undoList->p_begin("duplicate " + toString(SUMO_TAG_LANE));
546  GNEEdge* edge = &lane->getParentEdge();
547  const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
548  GNELane* newLane = new GNELane(*edge, lane->getIndex());
549  undoList->add(new GNEChange_Lane(edge, newLane, laneAttrs, true), true);
551  undoList->p_end();
552 }
553 
554 
555 bool
557  bool addRestriction = true;
558  if (vclass == SVC_PEDESTRIAN) {
559  GNEEdge& edge = lane->getParentEdge();
560  for (auto i : edge.getLanes()) {
561  if (i->isRestricted(SVC_PEDESTRIAN)) {
562  // prevent adding a 2nd sidewalk
563  addRestriction = false;
564  } else {
565  // ensure that the sidewalk is used exclusively
566  const SVCPermissions allOldWithoutPeds = edge.getNBEdge()->getPermissions(i->getIndex()) & ~SVC_PEDESTRIAN;
567  i->setAttribute(SUMO_ATTR_ALLOW, getVehicleClassNames(allOldWithoutPeds), undoList);
568  }
569  }
570  }
571  // restrict the lane
572  if (addRestriction) {
573  lane->setAttribute(SUMO_ATTR_ALLOW, toString(vclass), undoList);
574  return true;
575  } else {
576  return false;
577  }
578 }
579 
580 
581 bool
583  // First check that this lane is restricted
584  if (lane->isRestricted(SVC_PEDESTRIAN) == false &&
585  lane->isRestricted(SVC_BICYCLE) == false &&
586  lane->isRestricted(SVC_BUS) == false) {
587  return false;
588  }
589 
590  // Get all possible vehicle classes
591  std::vector<std::string> VClasses = SumoVehicleClassStrings.getStrings();
592  // Change allow and disallow attributes of lane
593  lane->setAttribute(SUMO_ATTR_ALLOW, joinToString(VClasses, " "), undoList);
594  lane->setAttribute(SUMO_ATTR_DISALLOW, std::string(), undoList);
595  return true;
596 }
597 
598 
599 bool
601  // First check that edge don't have a sidewalk
602  for (auto i : edge.getLanes()) {
603  if (i->isRestricted(vclass)) {
604  return false;
605  }
606  }
607  // duplicate last lane
608  duplicateLane(edge.getLanes().at(0), undoList);
609  // transform the created (last) lane to a sidewalk
610  return restrictLane(vclass, edge.getLanes()[0], undoList);
611 }
612 
613 
614 bool
616  // iterate over lanes of edge
617  for (auto i : edge.getLanes()) {
618  if (i->isRestricted(vclass)) {
619  // Delete lane
620  deleteLane(i, undoList);
621  return true;
622  }
623  }
624  return false;
625 }
626 
627 
628 void
630  if (!edge->deleteGeometry(pos, undoList)) {
631  deleteEdge(edge, undoList);
632  }
633 }
634 
635 
637 GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
638  undoList->p_begin("split " + toString(SUMO_TAG_EDGE));
639  deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
640  // compute geometry
641  const PositionVector& oldGeom = edge->getNBEdge()->getGeometry();
642  const double linePos = oldGeom.nearest_offset_to_point2D(pos, false);
643  std::pair<PositionVector, PositionVector> newGeoms = oldGeom.splitAt(linePos);
644  // figure out the new name
645  int posBase = 0;
646  std::string baseName = edge->getMicrosimID();
647  if (edge->wasSplit()) {
648  const std::string::size_type sep_index = baseName.rfind('.');
649  if (sep_index != std::string::npos) { // edge may have been renamed in between
650  std::string posString = baseName.substr(sep_index + 1);
651  try {
652  posBase = GNEAttributeCarrier::parse<int>(posString.c_str());
653  baseName = baseName.substr(0, sep_index); // includes the .
654  } catch (NumberFormatException) {
655  }
656  }
657  }
658  baseName += '.';
659  // create edges
660  if (newJunction == 0) {
661  newJunction = createJunction(pos, undoList);
662  }
663  GNEEdge* firstPart = createEdge(edge->getGNEJunctionSource(), newJunction, edge,
664  undoList, baseName + toString(posBase), true);
665  GNEEdge* secondPart = createEdge(newJunction, edge->getGNEJunctionDestiny(), edge,
666  undoList, baseName + toString(posBase + (int)linePos), true);
667  // fix first part of geometry
668  firstPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.first[0]), undoList);
669  firstPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.first[-1]), undoList);
670  newGeoms.first.pop_back();
671  newGeoms.first.erase(newGeoms.first.begin());
672  firstPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);
673  // fix second part of geometry
674  secondPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.second[0]), undoList);
675  secondPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.second[-1]), undoList);
676  newGeoms.second.pop_back();
677  newGeoms.second.erase(newGeoms.second.begin());
678  secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
679  // fix connections
680  for (auto con_it : edge->getNBEdge()->getConnections()) {
681  undoList->add(new GNEChange_Connection(secondPart, con_it, false, true), true);
682  }
683  undoList->p_end();
684  return newJunction;
685 }
686 
687 
688 void
689 GNENet::splitEdgesBidi(const std::set<GNEEdge*>& edges, const Position& pos, GNEUndoList* undoList) {
690  GNEJunction* newJunction = 0;
691  undoList->p_begin("split " + toString(SUMO_TAG_EDGE) + "s");
692  for (auto it : edges) {
693  newJunction = splitEdge(it, pos, undoList, newJunction);
694  }
695  undoList->p_end();
696 }
697 
698 
699 void
701  undoList->p_begin("reverse " + toString(SUMO_TAG_EDGE));
702  deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
703  GNEEdge* reversed = createEdge(edge->getGNEJunctionDestiny(), edge->getGNEJunctionSource(), edge, undoList, edge->getID(), false, true);
704  assert(reversed != 0);
705  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
706  undoList->p_end();
707 }
708 
709 
710 GNEEdge*
712  undoList->p_begin("add reversed " + toString(SUMO_TAG_EDGE));
713  GNEEdge* reversed = NULL;
715  // for rail edges, we assume bi-directional tracks are wanted
716  reversed = createEdge(edge->getGNEJunctionDestiny(), edge->getGNEJunctionSource(), edge, undoList, "-" + edge->getID(), false, true);
717  assert(reversed != 0);
718  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
719  } else {
720  // if the edge is centered it should probably connect somewhere else
721  // make it easy to move and reconnect it
722  PositionVector orig = edge->getNBEdge()->getGeometry();
723  PositionVector origInner = edge->getNBEdge()->getInnerGeometry();
724  const double tentativeShift = edge->getNBEdge()->getTotalWidth() + 2;
725  orig.move2side(-tentativeShift);
726  origInner.move2side(-tentativeShift);
727  GNEJunction* src = createJunction(orig.back(), undoList);
728  GNEJunction* dest = createJunction(orig.front(), undoList);
729  reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true);
730  assert(reversed != 0);
731  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
732  // select the new edge and its nodes
733  std::set<GUIGlID> toSelect;
734  toSelect.insert(reversed->getGlID());
735  toSelect.insert(src->getGlID());
736  toSelect.insert(dest->getGlID());
737  undoList->add(new GNEChange_Selection(this, toSelect, gSelected.getSelected(), true), true);
738  }
739  undoList->p_end();
740  return reversed;
741 }
742 
743 
744 void
746  undoList->p_begin("merge " + toString(SUMO_TAG_JUNCTION) + "s");
747  // position of moved and target are probably a bit different (snap radius)
748  Position oldPos = moved->getNBNode()->getPosition();
749  moved->moveJunctionGeometry(target->getNBNode()->getPosition());
750  // register the move with undolist (must happend within the undo group)
751  moved->commitGeometryMoving(oldPos, undoList);
752  // deleting edges changes in the underlying EdgeVector so we have to make a copy
753  const EdgeVector incoming = moved->getNBNode()->getIncomingEdges();
754  for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) {
755  GNEEdge* oldEdge = myEdges[(*it)->getID()];
756  remapEdge(oldEdge, oldEdge->getGNEJunctionSource(), target, undoList);
757  }
758  // deleting edges changes in the underlying EdgeVector so we have to make a copy
759  const EdgeVector outgoing = moved->getNBNode()->getOutgoingEdges();
760  for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
761  GNEEdge* oldEdge = myEdges[(*it)->getID()];
762  remapEdge(oldEdge, target, oldEdge->getGNEJunctionDestiny(), undoList);
763  }
764  deleteJunction(moved, undoList);
765  undoList->p_end();
766 }
767 
768 
769 void
770 GNENet::remapEdge(GNEEdge* oldEdge, GNEJunction* from, GNEJunction* to, GNEUndoList* undoList, bool keepEndpoints) {
771  // remove all crossings asociated to this edge before remap
772  std::vector<GNECrossing*> crossingsOfOldEdge = oldEdge->getGNECrossings();
773  for (auto i : crossingsOfOldEdge) {
774  deleteCrossing(i, undoList);
775  }
776  // delete first so we can reuse the name, reference stays valid
777  deleteEdge(oldEdge, undoList);
778  if (from != to) {
779  GNEEdge* newEdge = createEdge(from, to, oldEdge, undoList, oldEdge->getMicrosimID(), false, true);
780  newEdge->setAttribute(SUMO_ATTR_SHAPE, oldEdge->getAttribute(SUMO_ATTR_SHAPE), undoList);
781  if (keepEndpoints) {
782  // preserve endpoints even if they where not customized
783  newEdge->setAttribute(GNE_ATTR_SHAPE_START, toString(oldEdge->getNBEdge()->getGeometry().front()), undoList);
784  newEdge->setAttribute(GNE_ATTR_SHAPE_END, toString(oldEdge->getNBEdge()->getGeometry().back()), undoList);
785  }
786  }
787  // @todo remap connectivity as well
788 }
789 
790 
791 bool
793  // Check that there isn't another junction in the same position as Pos
794  for (auto i : myJunctions) {
795  if (i.second->getPositionInView() == pos) {
796  return false;
797  }
798  }
799  return true;
800 }
801 
802 
803 void
805  // compute without volatile options and update network
806  computeAndUpdate(oc, false);
807  // write network
809 }
810 
811 
812 void
813 GNENet::saveAdditionals(const std::string& filename, bool volatileOptionsEnabled) {
814  // obtain invalid stopping places and detectors
815  std::vector<GNEStoppingPlace*> invalidStoppingPlaces;
816  std::vector<GNEDetector*> invalidDetectors;
817  for (auto i : myAdditionals) {
818  GNEStoppingPlace* stoppingPlace = dynamic_cast<GNEStoppingPlace*>(i.second);
819  GNEDetector* detector = dynamic_cast<GNEDetector*>(i.second);
820  // check if has to be fixed
821  if ((stoppingPlace != NULL) && (stoppingPlace->areStoppingPlacesPositionsFixed() == false)) {
822  invalidStoppingPlaces.push_back(stoppingPlace);
823  } else if ((detector != NULL) && (detector->isDetectorPositionFixed() == false)) {
824  invalidDetectors.push_back(detector);
825  }
826  }
827  // if there are invalid StoppingPlaces or detectors, open GNEDialog_FixAdditionalPositions
828  if (invalidStoppingPlaces.size() > 0 || invalidDetectors.size() > 0) {
829  // 0 -> Canceled Saving, with or whithout selecting invalid stopping places and E2
830  // 1 -> Invalid stoppingPlaces and E2 fixed, friendlyPos enabled, or saved with invalid positions
831  GNEDialog_FixAdditionalPositions fixAdditionalPositionsDialog(myViewNet, invalidStoppingPlaces, invalidDetectors);
832  if (fixAdditionalPositionsDialog.execute() == 0) {
833  // Here a console message
834  ;
835  } else {
836  // save additionals
837  OutputDevice& device = OutputDevice::getDevice(filename);
838  device.openTag("additionals");
839  for (auto i : myAdditionals) {
840  i.second->writeAdditional(device, volatileOptionsEnabled);
841  }
842  device.close();
843  }
844  // set focus again in viewNet
845  myViewNet->setFocus();
846  } else {
847  OutputDevice& device = OutputDevice::getDevice(filename);
848  device.openTag("additionals");
849  for (auto i : myAdditionals) {
850  i.second->writeAdditional(device, volatileOptionsEnabled);
851  }
852  device.close();
853  }
854  // change value of flag
855  myAdditionalsSaved = true;
856  // show debug information
857  if(OptionsCont::getOptions().getBool("gui-testing-debug")) {
858  WRITE_WARNING("Additionals saved");
859  }
860 }
861 
862 
863 void
865  // compute without volatile options
866  computeAndUpdate(oc, false);
868 }
869 
870 
871 void
873  // compute without volatile options
874  computeAndUpdate(oc, false);
876 }
877 
878 
879 void
881  myViewNet = viewNet;
882 }
883 
884 
886 GNENet::retrieveJunction(const std::string& id, bool failHard) {
887  if (myJunctions.count(id)) {
888  return myJunctions[id];
889  } else if (failHard) {
890  // If junction wasn't found, throw exception
891  throw UnknownElement("Junction " + id);
892  } else {
893  return NULL;
894  }
895 }
896 
897 
898 GNEEdge*
899 GNENet::retrieveEdge(const std::string& id, bool failHard) {
900  auto i = myEdges.find(id);
901  // If edge was fund
902  if (i != myEdges.end()) {
903  return i->second;
904  } else if (failHard) {
905  // If edge wasn't found, throw exception
906  throw UnknownElement("Edge " + id);
907  } else {
908  return NULL;
909  }
910 }
911 
912 
913 GNEEdge*
914 GNENet::retrieveEdge(GNEJunction* from, GNEJunction* to, bool failHard) {
915  assert((from != NULL) && (to != NULL));
916  // iterate over Junctions of net
917  for (auto i : myEdges) {
918  if ((i.second->getGNEJunctionSource() == from) && (i.second->getGNEJunctionDestiny() == to)) {
919  return i.second;
920  }
921  }
922  // if edge wasn' found, throw exception or return NULL
923  if (failHard) {
924  throw UnknownElement("Edge with from='" + from->getID() + "' and to='" + to->getID() + "'");
925  } else {
926  return NULL;
927  }
928 }
929 
930 
931 std::vector<GNEEdge*>
932 GNENet::retrieveEdges(bool onlySelected) {
933  std::vector<GNEEdge*> result;
934  for (auto it : myEdges) {
935  if (!onlySelected || gSelected.isSelected(GLO_EDGE, it.second->getGlID())) {
936  result.push_back(it.second);
937  }
938  }
939  return result;
940 }
941 
942 
943 std::vector<GNELane*>
944 GNENet::retrieveLanes(bool onlySelected) {
945  std::vector<GNELane*> result;
946  for (auto it : myEdges) {
947  for (auto it_lane : it.second->getLanes()) {
948  if (!onlySelected || gSelected.isSelected(GLO_LANE, it_lane->getGlID())) {
949  result.push_back(it_lane);
950  }
951  }
952  }
953  return result;
954 }
955 
956 
957 GNELane*
958 GNENet::retrieveLane(const std::string& id, bool failHard) {
959  const std::string edge_id = SUMOXMLDefinitions::getEdgeIDFromLane(id);
960  GNEEdge* edge = retrieveEdge(edge_id, failHard);
961  if (edge != 0) {
962  const GNEEdge::LaneVector& lanes = edge->getLanes();
963  for (GNEEdge::LaneVector::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
964  if ((*it_lane)->getID() == id) {
965  return (*it_lane);
966  }
967  }
968  if (failHard) {
969  // Throw exception if failHard is enabled
970  throw UnknownElement(toString(SUMO_TAG_LANE) + " " + id);
971  }
972  }
973  return 0;
974 }
975 
976 
977 std::vector<GNEJunction*>
978 GNENet::retrieveJunctions(bool onlySelected) {
979  std::vector<GNEJunction*> result;
980  for (auto it : myJunctions) {
981  if (!onlySelected || gSelected.isSelected(GLO_JUNCTION, it.second->getGlID())) {
982  result.push_back(it.second);
983  }
984  }
985  return result;
986 }
987 
988 
989 void
993  update();
994 }
995 
996 
997 void
999  GNEAdditionals::iterator positionToRemove = myAdditionals.find(std::pair<std::string, SumoXMLTag>(additional->getID(), additional->getTag()));
1000  // Check if additional element exists before refresh
1001  if (positionToRemove != myAdditionals.end()) {
1002  myGrid.removeAdditionalGLObject(additional);
1003  myGrid.addAdditionalGLObject(additional);
1004  update();
1005  }
1006 }
1007 
1008 
1009 std::string
1011  int counter = 0;
1012  while (myAdditionals.find(std::pair<std::string, SumoXMLTag>("vaporizer_" + toString(counter), SUMO_TAG_VAPORIZER)) != myAdditionals.end()) {
1013  counter++;
1014  }
1015  return "vaporizer_" + toString(counter);
1016 }
1017 
1018 
1019 std::vector<GNEAttributeCarrier*>
1020 GNENet::retrieveAttributeCarriers(const std::set<GUIGlID>& ids, GUIGlObjectType type) {
1021  std::vector<GNEAttributeCarrier*> result;
1022  for (auto it : ids) {
1024  if (object != 0) {
1025  std::string id = object->getMicrosimID();
1027  GNEAttributeCarrier* ac = 0;
1028  switch (type) {
1029  case GLO_JUNCTION:
1030  ac = dynamic_cast<GNEJunction*>(object);
1031  break;
1032  case GLO_EDGE:
1033  ac = dynamic_cast<GNEEdge*>(object);
1034  break;
1035  case GLO_LANE:
1036  ac = dynamic_cast<GNELane*>(object);
1037  break;
1038  case GLO_ADDITIONAL:
1039  ac = dynamic_cast<GNEAdditional*>(object);
1040  break;
1041  case GLO_CONNECTION:
1042  ac = dynamic_cast<GNEConnection*>(object);
1043  break;
1044  case GLO_CROSSING:
1045  ac = dynamic_cast<GNECrossing*>(object);
1046  break;
1047  case GLO_POLYGON:
1048  ac = dynamic_cast<GNEPoly*>(object);
1049  break;
1050  case GLO_POI:
1051  ac = dynamic_cast<GNEPOI*>(object);
1052  break;
1053  default:
1054  break;
1055  }
1056  if (ac == 0) {
1057  throw ProcessError("GUIGlObject does not match the declared type");
1058  } else {
1059  result.push_back(ac);
1060  }
1061  } else {
1062  throw ProcessError("Attempted to retrieve non-existant GUIGlObject");
1063  }
1064  }
1065  return result;
1066 }
1067 
1068 
1069 std::set<GUIGlID>
1071  std::set<GUIGlID> result;
1072  switch (type) {
1073  case GLO_MAX: {
1074  std::set<GUIGlObjectType> knownTypes;
1075  knownTypes.insert(GLO_JUNCTION);
1076  knownTypes.insert(GLO_EDGE);
1077  knownTypes.insert(GLO_LANE);
1078  // knownTypes.insert(GLO_TLLOGIC); makes no sense to include them
1079  knownTypes.insert(GLO_ADDITIONAL);
1080  knownTypes.insert(GLO_CONNECTION);
1081  knownTypes.insert(GLO_CROSSING);
1082  knownTypes.insert(GLO_POLYGON);
1083  knownTypes.insert(GLO_POI);
1084  // obtain all GLIDS calling getGlIDs(...) recursively
1085  for (auto it : knownTypes) {
1086  const std::set<GUIGlID> tmp = getGlIDs(it);
1087  result.insert(tmp.begin(), tmp.end());
1088  }
1089  break;
1090  }
1091  case GLO_JUNCTION:
1092  for (auto it : myJunctions) {
1093  result.insert(it.second->getGlID());
1094  }
1095  break;
1096  case GLO_EDGE:
1097  for (auto it : myEdges) {
1098  result.insert(it.second->getGlID());
1099  }
1100  break;
1101  case GLO_LANE: {
1102  for (auto i : myEdges) {
1103  // iterate over every edge's lane
1104  for (auto j : i.second->getLanes()) {
1105  result.insert(j->getGlID());
1106  }
1107  }
1108  break;
1109  }
1110  case GLO_TLLOGIC: {
1111  // return all junctions which have a traffic light (we do not have a GUIGlObject for each traffic light)
1112  for (auto it : myJunctions) {
1113  if (it.second->getNBNode()->isTLControlled()) {
1114  result.insert(it.second->getGlID());
1115  }
1116  }
1117  break;
1118  }
1119  case GLO_ADDITIONAL: {
1120  // Iterate over all additionals of net
1121  for (auto it : myAdditionals) {
1122  // Insert every additional in result
1123  result.insert(it.second->getGlID());
1124  }
1125  break;
1126  }
1127  case GLO_CONNECTION: {
1128  for (auto i : myEdges) {
1129  // Iterate over edge's connections
1130  for (auto j : i.second->getGNEConnections()) {
1131  // Insert every connection of edge in result
1132  result.insert(j->getGlID());
1133  }
1134  }
1135  break;
1136  }
1137  case GLO_CROSSING: {
1138  for (auto i : myJunctions) {
1139  // Iterate over junction's crossings
1140  for (auto j : i.second->getGNECrossings()) {
1141  // Insert every crossing of junction in result
1142  result.insert(j->getGlID());
1143  }
1144  }
1145  break;
1146  }
1147  case GLO_POLYGON: {
1148  for (auto i : myPolygons.getMyMap()) {
1149  result.insert(dynamic_cast<GNEPoly*>(i.second)->getGlID());
1150  }
1151  break;
1152  }
1153  case GLO_POI: {
1154  for (auto i : myPOIs.getMyMap()) {
1155  result.insert(dynamic_cast<GNEPOI*>(i.second)->getGlID());
1156  }
1157  break;
1158  }
1159  default: // add other types once we know them
1160  break;
1161  }
1162  return result;
1163 }
1164 
1165 
1166 void
1167 GNENet::computeEverything(GNEApplicationWindow* window, bool force, bool volatileOptions, std::string additionalPath, std::string shapePath) {
1168  if (!myNeedRecompute) {
1169  if (force) {
1170  if (volatileOptions) {
1171  window->setStatusBarText("Forced computing junctions with volatile options ...");
1172  } else {
1173  window->setStatusBarText("Forced computing junctions ...");
1174  }
1175  } else {
1176  return;
1177  }
1178  } else {
1179  if (volatileOptions) {
1180  window->setStatusBarText("Computing junctions with volatile options ...");
1181  } else {
1182  window->setStatusBarText("Computing junctions ...");
1183  }
1184  }
1185  // compute
1187  computeAndUpdate(oc, volatileOptions);
1188 
1189  // load additionals if was recomputed with volatile options
1190  if (additionalPath != "") {
1191  // Create additional handler
1192  GNEAdditionalHandler additionalHandler(additionalPath, myViewNet, false);
1193  // Run parser
1194  if (!XMLSubSys::runParser(additionalHandler, additionalPath, false)) {
1195  WRITE_MESSAGE("Loading of " + additionalPath + " failed.");
1196  } else {
1197  // reset last tag (needed to avoid invalid E3s)
1198  additionalHandler.resetLastTag();
1199  update();
1200  }
1201  }
1202  // load shapes if was recomputed with volatile options
1203  if (shapePath != "") {
1204  GNEApplicationWindow::GNEShapeHandler handler(shapePath, this);
1205  if (!XMLSubSys::runParser(handler, shapePath, false)) {
1206  WRITE_MESSAGE("Loading of " + shapePath + " failed.");
1207  }
1208  }
1209  window->getApp()->endWaitCursor();
1210  window->setStatusBarText("Finished computing junctions.");
1211  update();
1212 }
1213 
1214 
1215 void
1217  // recompute tl-logics
1220  // iterate over traffic lights definitions
1221  for (auto it : junction->getNBNode()->getControllingTLS()) {
1222  it->setParticipantsInformation();
1223  it->setTLControllingInformation();
1224  tllCont.computeSingleLogic(oc, it);
1225  }
1226 
1227  // @todo compute connections etc...
1228 }
1229 
1230 
1231 void
1233  myNeedRecompute = true;
1234 }
1235 
1236 void
1238  if((myAdditionalsSaved == true) && OptionsCont::getOptions().getBool("gui-testing-debug")) {
1239  WRITE_WARNING("Additionals has to be saved");
1240  }
1241  myAdditionalsSaved = false;
1243 }
1244 
1245 
1246 void
1248  if((myShapesSaved == true) && OptionsCont::getOptions().getBool("gui-testing-debug")) {
1249  WRITE_WARNING("Shapes has to be saved");
1250  }
1251  myShapesSaved = false;
1253 }
1254 
1255 
1256 bool
1258  for (auto n : myJunctions) {
1259  if (n.second->getGNECrossings().size() > 0) {
1260  return true;
1261  }
1262  }
1263  return false;
1264 }
1265 
1266 
1267 FXApp*
1269  return myViewNet->getApp();
1270 }
1271 
1272 
1273 NBNetBuilder*
1275  return myNetBuilder;
1276 }
1277 
1278 
1279 bool
1281  std::vector<GNEJunction*> selectedJunctions = retrieveJunctions(true);
1282  if (selectedJunctions.size() < 2) {
1283  return false;
1284  }
1285  EdgeVector allIncoming;
1286  EdgeVector allOutgoing;
1287  std::set<NBNode*> cluster;
1288  for (auto it : selectedJunctions) {
1289  cluster.insert(it->getNBNode());
1290  const EdgeVector& incoming = it->getNBNode()->getIncomingEdges();
1291  allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end());
1292  const EdgeVector& outgoing = it->getNBNode()->getOutgoingEdges();
1293  allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end());
1294  }
1295  // create new junction
1296  Position pos;
1297  Position oldPos;
1298  bool setTL;
1299  std::string id;
1300  TrafficLightType type;
1301  myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type);
1302  // save position
1303  oldPos = pos;
1304 
1305  // Check that there isn't another junction in the same position as Pos but doesn't belong to cluster
1306  for (auto i : myJunctions) {
1307  if ((i.second->getPositionInView() == pos) && (cluster.find(i.second->getNBNode()) == cluster.end())) {
1308  // show warning in gui testing debug mode
1309  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1310  WRITE_WARNING("Opening FXMessageBox 'Join non-selected junction'");
1311  }
1312  // Ask confirmation to user
1313  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1314  ("Position of joined " + toString(SUMO_TAG_JUNCTION)).c_str(), "%s",
1315  ("There is another unselected " + toString(SUMO_TAG_JUNCTION) + " in the same position of joined " + toString(SUMO_TAG_JUNCTION) +
1316  + ".\nIt will be joined with the other selected " + toString(SUMO_TAG_JUNCTION) + "s. Continue?").c_str());
1317  if (answer != 1) { // 1:yes, 2:no, 4:esc
1318  // write warning if netedit is running in testing mode
1319  if ((answer == 2) && (OptionsCont::getOptions().getBool("gui-testing-debug"))) {
1320  WRITE_WARNING("Closed FXMessageBox 'Join non-selected junction' with 'No'");
1321  } else if ((answer == 4) && (OptionsCont::getOptions().getBool("gui-testing-debug"))) {
1322  WRITE_WARNING("Closed FXMessageBox 'Join non-selected junction' with 'ESC'");
1323  }
1324  return false;
1325  } else {
1326  // write warning if netedit is running in testing mode
1327  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1328  WRITE_WARNING("Closed FXMessageBox 'Join non-selected junction' with 'Yes'");
1329  }
1330  // select conflicted junction an join all again
1331  gSelected.select(i.second->getGlID());
1332  return joinSelectedJunctions(undoList);
1333  }
1334  }
1335  }
1336 
1337  // use checkJunctionPosition to avoid conflicts with junction in the same position as others
1338  while (checkJunctionPosition(pos) == false) {
1339  pos.setx(pos.x() + 0.1);
1340  pos.sety(pos.y() + 0.1);
1341  }
1342 
1343  // start with the join selected junctions
1344  undoList->p_begin("Join selected " + toString(SUMO_TAG_JUNCTION) + "s");
1345 
1346  // first remove all crossing of the involved junctions and edges
1347  for (auto i : selectedJunctions) {
1348 
1349  while (i->getGNECrossings().size() > 0) {
1350  deleteCrossing(i->getGNECrossings().front(), undoList);
1351  }
1352  }
1353 
1354  // #3128 this is not undone when calling 'undo'
1356  GNEJunction* joined = createJunction(pos, undoList);
1357  if (setTL) {
1359  // XXX ticket831
1360  //joined-><getTrafficLight>->setAttribute(SUMO_ATTR_TYPE, toString(type), undoList);
1361  }
1362  // remap edges
1363  for (auto it : allIncoming) {
1364  GNEEdge* oldEdge = myEdges[it->getID()];
1365  remapEdge(oldEdge, oldEdge->getGNEJunctionSource(), joined, undoList, true);
1366  }
1367  for (auto it : allOutgoing) {
1368  GNEEdge* oldEdge = myEdges[it->getID()];
1369  remapEdge(oldEdge, joined, oldEdge->getGNEJunctionDestiny(), undoList, true);
1370  }
1371  // delete original junctions
1372  for (auto it : selectedJunctions) {
1373  deleteJunction(it, undoList);
1374  }
1375  joined->setAttribute(SUMO_ATTR_ID, id, undoList);
1376 
1377  // check if joined junction had to change their original position to avoid errors
1378  if (pos != oldPos) {
1379  joined->setAttribute(SUMO_ATTR_POSITION, toString(oldPos), undoList);
1380  }
1381  undoList->p_end();
1382  return true;
1383 }
1384 
1385 
1386 bool
1388  // obtain current net's crossings
1389  std::vector<GNECrossing*> myNetCrossings;
1390  for (auto it : myJunctions) {
1391  myNetCrossings.reserve(myNetCrossings.size() + it.second->getGNECrossings().size());
1392  myNetCrossings.insert(myNetCrossings.end(), it.second->getGNECrossings().begin(), it.second->getGNECrossings().end());
1393  }
1394  // obtain invalid crossigns
1395  std::vector<GNECrossing*> myInvalidCrossings;
1396  for (auto i = myNetCrossings.begin(); i != myNetCrossings.end(); i++) {
1397  if ((*i)->getNBCrossing()->valid == false) {
1398  myInvalidCrossings.push_back(*i);
1399  }
1400  }
1401 
1402  if (myInvalidCrossings.empty()) {
1403  // show warning in gui testing debug mode
1404  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1405  WRITE_WARNING("Opening FXMessageBox 'No crossing to remove'");
1406  }
1407  // open a dialog informing that there isn't crossing to remove
1408  FXMessageBox::warning(getApp(), MBOX_OK,
1409  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1410  ("There is no invalid " + toString(SUMO_TAG_CROSSING) + "s to remove").c_str());
1411  // show warning in gui testing debug mode
1412  WRITE_WARNING("Closed FXMessageBox 'No crossing to remove' with 'OK'");
1413  } else {
1414  std::string plural = myInvalidCrossings.size() == 1 ? ("") : ("s");
1415  // show warning in gui testing debug mode
1416  if (OptionsCont::getOptions().getBool("gui-testing-debug")) {
1417  WRITE_WARNING("Opening FXMessageBox 'clear crossings'");
1418  }
1419  // Ask confirmation to user
1420  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1421  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1422  ("Clear " + toString(SUMO_TAG_CROSSING) + plural + " will be removed. Continue?").c_str());
1423  if (answer != 1) { // 1:yes, 2:no, 4:esc
1424  // write warning if netedit is running in testing mode
1425  if ((answer == 2) && (OptionsCont::getOptions().getBool("gui-testing-debug"))) {
1426  WRITE_WARNING("Closed FXMessageBox 'clear crossings' with 'No'");
1427  } else if ((answer == 4) && (OptionsCont::getOptions().getBool("gui-testing-debug"))) {
1428  WRITE_WARNING("Closed FXMessageBox 'clear crossings' with 'ESC'");
1429  }
1430  } else {
1431  undoList->p_begin("Clean " + toString(SUMO_TAG_CROSSING) + "s");
1432  for (auto i = myInvalidCrossings.begin(); i != myInvalidCrossings.end(); i++) {
1433  deleteCrossing((*i), undoList);
1434  }
1435  undoList->p_end();
1436  }
1437  }
1438  return 1;
1439 }
1440 
1441 
1442 void
1444  undoList->p_begin("Clean " + toString(SUMO_TAG_JUNCTION) + "s");
1445  std::vector<GNEJunction*> toRemove;
1446  for (auto it : myJunctions) {
1447  GNEJunction* junction = it.second;
1448  if (junction->getNBNode()->getEdges().size() == 0) {
1449  toRemove.push_back(junction);
1450  }
1451  }
1452  for (auto it : toRemove) {
1453  deleteJunction(it, undoList);
1454  }
1455  undoList->p_end();
1456 }
1457 
1458 
1459 void
1461  undoList->p_begin("Replace junction by geometry");
1462  assert(junction->getNBNode()->checkIsRemovable());
1463  std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
1464  for (auto j : toJoin) {
1465  GNEEdge* begin = myEdges[j.first->getID()];
1466  GNEEdge* continuation = myEdges[j.second->getID()];
1467  // remove connections between the edges
1468  std::vector<NBEdge::Connection> connections = begin->getNBEdge()->getConnections();
1469  for (auto con : connections) {
1470  undoList->add(new GNEChange_Connection(begin, con, false, false), true);
1471  }
1472  // replace
1473  replaceIncomingEdge(continuation, begin, undoList);
1474  // fix shape
1475  PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
1476  if (begin->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1477  newShape.push_back(junction->getNBNode()->getPosition());
1478  } else {
1479  newShape.push_back(begin->getNBEdge()->getGeometry()[-1]);
1480  }
1481  if (continuation->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1482  newShape.push_back_noDoublePos(junction->getNBNode()->getPosition());
1483  } else {
1484  newShape.push_back_noDoublePos(continuation->getNBEdge()->getGeometry()[0]);
1485  }
1486  newShape.append(continuation->getNBEdge()->getInnerGeometry());
1487  begin->setAttribute(GNE_ATTR_SHAPE_END, continuation->getAttribute(GNE_ATTR_SHAPE_END), undoList);
1488  begin->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
1489  }
1490  deleteJunction(junction, undoList);
1491  undoList->p_end();
1492 }
1493 
1494 
1495 void
1496 GNENet::renameEdge(GNEEdge* edge, const std::string& newID) {
1497  myEdges.erase(edge->getNBEdge()->getID());
1498  myNetBuilder->getEdgeCont().rename(edge->getNBEdge(), newID);
1499  edge->setMicrosimID(newID);
1500  myEdges[newID] = edge;
1501  // rename all connections related to this edge
1502  for (auto i : edge->getLanes()) {
1503  i->updateConnectionIDs();
1504  }
1505 }
1506 
1507 
1508 void
1509 GNENet::changeEdgeEndpoints(GNEEdge* edge, const std::string& newSource, const std::string& newDest) {
1510  NBNode* from = retrieveJunction(newSource)->getNBNode();
1511  NBNode* to = retrieveJunction(newDest)->getNBNode();
1512  edge->getNBEdge()->reinitNodes(from, to);
1513  requireRecompute();
1514  update();
1515 }
1516 
1517 
1518 GNEViewNet*
1520  return myViewNet;
1521 }
1522 
1523 
1526  return myNetBuilder->getTLLogicCont();
1527 }
1528 
1529 
1530 void
1531 GNENet::renameJunction(GNEJunction* junction, const std::string& newID) {
1532  myJunctions.erase(junction->getNBNode()->getID());
1533  myNetBuilder->getNodeCont().rename(junction->getNBNode(), newID);
1534  junction->setMicrosimID(newID);
1535  myJunctions[newID] = junction;
1536 }
1537 
1538 
1539 void
1541  myExplicitTurnarounds.insert(id);
1542 }
1543 
1544 
1545 void
1547  myExplicitTurnarounds.erase(id);
1548 }
1549 
1550 
1551 void
1552 GNENet::moveSelection(const Position& moveSrc, const Position& moveDest) {
1553  Position delta = moveDest - moveSrc;
1554  // obtain Junctios to move
1555  std::set<GNEJunction*> junctionSet;
1556  std::vector<GNEJunction*> junctions = retrieveJunctions(true);
1557  // move junctions
1558  for (auto it : junctions) {
1559  Position newPos = it->getNBNode()->getPosition() + delta;
1560  it->moveJunctionGeometry(newPos);
1561  junctionSet.insert(it);
1562  }
1563 
1564  // move edge geometry (endpoints are already moved)
1565  std::vector<GNEEdge*> edges = retrieveEdges(true);
1566  for (auto it : edges) {
1567  if (it) {
1568  if (junctionSet.count(it->getGNEJunctionSource()) > 0 &&
1569  junctionSet.count(it->getGNEJunctionDestiny()) > 0) {
1570  // edge and its endpoints are selected, move all the inner points as well
1571  it->moveGeometry(delta);
1572  } else {
1573  // move only geometry near mouse
1574  it->moveGeometry(moveSrc, delta, true);
1575  }
1576  }
1577  }
1578 }
1579 
1580 
1581 void
1583  undoList->p_begin("move selection");
1584  // register moved junctions
1585  std::set<GNEJunction*> junctionSet;
1586  std::vector<GNEJunction*> junctions = retrieveJunctions(true);
1587  for (auto it : junctions) {
1588  junctionSet.insert(it);
1589  }
1590 
1591  // register moved edge geometry (endpoints are already moved)
1592  std::vector<GNEEdge*> edges = retrieveEdges(true);
1593  for (auto it : edges) {
1594  if (it) {
1595  const std::string& newShape = it->getAttribute(SUMO_ATTR_SHAPE);
1596  it->setAttribute(SUMO_ATTR_SHAPE, newShape, undoList);
1597  }
1598  }
1599  undoList->p_end();
1600 }
1601 
1602 
1603 void
1604 GNENet::insertAdditional(GNEAdditional* additional, bool hardFail) {
1605  // Check if additional element exists before insertion
1606  if (myAdditionals.find(std::pair<std::string, SumoXMLTag>(additional->getID(), additional->getTag())) != myAdditionals.end()) {
1607  // Throw exception only if hardFail is enabled
1608  if (hardFail) {
1609  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' already exist");
1610  }
1611  } else {
1612  myAdditionals[std::pair<std::string, SumoXMLTag>(additional->getID(), additional->getTag())] = additional;
1613  myGrid.addAdditionalGLObject(additional);
1614  update();
1615  // additionals has to be saved
1617  }
1618 }
1619 
1620 
1621 void
1623  GNEAdditionals::iterator additionalToRemove = myAdditionals.find(std::pair<std::string, SumoXMLTag>(additional->getID(), additional->getTag()));
1624  // Check if additional element exists before deletion
1625  if (additionalToRemove == myAdditionals.end()) {
1626  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' doesn't exist");
1627  } else {
1628  myAdditionals.erase(additionalToRemove);
1629  myGrid.removeAdditionalGLObject(additional);
1630  update();
1631  // additionals has to be saved
1633  }
1634 }
1635 
1636 
1637 void
1638 GNENet::updateAdditionalID(const std::string& oldID, GNEAdditional* additional) {
1639  GNEAdditionals::iterator additionalToUpdate = myAdditionals.find(std::pair<std::string, SumoXMLTag>(oldID, additional->getTag()));
1640  if (additionalToUpdate == myAdditionals.end()) {
1641  throw ProcessError(toString(additional->getTag()) + " with old ID='" + oldID + "' doesn't exist");
1642  } else {
1643  // remove an insert additional again into container
1644  myAdditionals.erase(additionalToUpdate);
1645  myAdditionals[std::pair<std::string, SumoXMLTag>(additional->getID(), additional->getTag())] = additional;
1646  // additionals has to be saved
1648  }
1649 }
1650 
1651 
1653 GNENet::retrieveAdditional(const std::string& id, bool hardFail) const {
1654  for (auto i : myAdditionals) {
1655  if (i.second->getID() == id) {
1656  return i.second;
1657  }
1658  }
1659  if (hardFail) {
1660  throw ProcessError("Attempted to retrieve non-existant additional");
1661  } else {
1662  return NULL;
1663  }
1664 }
1665 
1666 
1667 std::vector<GNEAdditional*>
1668 GNENet::retrieveAdditionals(bool onlySelected) {
1669  std::vector<GNEAdditional*> result;
1670  for (auto it : myAdditionals) {
1671  if (!onlySelected || gSelected.isSelected(GLO_ADDITIONAL, it.second->getGlID())) {
1672  result.push_back(it.second);
1673  }
1674  }
1675  return result;
1676 }
1677 
1678 
1680 GNENet::getAdditional(SumoXMLTag type, const std::string& id) const {
1681  if (myAdditionals.empty()) {
1682  return NULL;
1683  } else if (myAdditionals.find(std::pair<std::string, SumoXMLTag>(id, type)) != myAdditionals.end()) {
1684  return myAdditionals.at(std::pair<std::string, SumoXMLTag>(id, type));
1685  } else {
1686  return NULL;
1687  }
1688 }
1689 
1690 
1691 std::string
1692 GNENet::getAdditionalID(SumoXMLTag type, const GNELane* lane, const double pos) const {
1693  for (auto it : myAdditionals) {
1694  if ((it.second->getTag() == type) && (it.second->getLane() != NULL) && (it.second->getLane() == lane) && (fabs(it.second->getPositionInView().x() - pos) < POSITION_EPS)) {
1695  return it.second->getID();
1696  }
1697  }
1698  return "";
1699 }
1700 
1701 
1702 std::vector<GNEAdditional*>
1704  std::vector<GNEAdditional*> vectorOfAdditionals;
1705  for (auto i : myAdditionals) {
1706  if (type == SUMO_TAG_NOTHING || type == i.second->getTag()) {
1707  vectorOfAdditionals.push_back(i.second);
1708  }
1709  }
1710  return vectorOfAdditionals;
1711 }
1712 
1713 
1714 int
1716  int counter = 0;
1717  for (auto i : myAdditionals) {
1718  if (type == SUMO_TAG_NOTHING || type == i.second->getTag()) {
1719  counter++;
1720  }
1721  }
1722  return counter;
1723 }
1724 
1725 
1726 const GNECalibratorRoute&
1727 GNENet::getGNECalibratorRoute(const std::string& calibratorRouteID) const {
1728  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1729  for (auto i : calibrators) {
1730  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1731  if (calibrator->routeExists(calibratorRouteID)) {
1732  return calibrator->getCalibratorRoute(calibratorRouteID);
1733  }
1734  }
1735  throw InvalidArgument("A " + toString(SUMO_TAG_VTYPE) + "'s " + toString(SUMO_TAG_VTYPE) + " with ID = '" + calibratorRouteID + "' doesn't exists");
1736 }
1737 
1738 
1740 GNENet::getGNECalibratorVehicleType(const std::string& calibratorVehicleTypeID) const {
1741  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1742  for (auto i : calibrators) {
1743  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1744  if (calibrator->vehicleTypeExists(calibratorVehicleTypeID)) {
1745  return calibrator->getCalibratorVehicleType(calibratorVehicleTypeID);
1746  }
1747  }
1748  throw InvalidArgument("A " + toString(SUMO_TAG_VTYPE) + "'s " + toString(SUMO_TAG_VTYPE) + " with ID = '" + calibratorVehicleTypeID + "' doesn't exists");
1749 }
1750 
1751 
1752 const GNECalibratorFlow&
1753 GNENet::getGNECalibratorFlow(const std::string& calibratorFlowID) const {
1754  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1755  for (auto i : calibrators) {
1756  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1757  if (calibrator->flowExists(calibratorFlowID)) {
1758  return calibrator->getCalibratorFlow(calibratorFlowID);
1759  }
1760  }
1761  throw InvalidArgument("A " + toString(SUMO_TAG_VTYPE) + "'s " + toString(SUMO_TAG_VTYPE) + " with ID = '" + calibratorFlowID + "' doesn't exists");
1762 }
1763 
1764 
1765 bool
1766 GNENet::routeExists(const std::string& routeID) const {
1767  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1768  for (auto i : calibrators) {
1769  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1770  if (calibrator->routeExists(routeID)) {
1771  return true;
1772  }
1773  }
1774  return false;
1775 }
1776 
1777 
1778 bool
1779 GNENet::vehicleTypeExists(const std::string& vehicleTypeID) const {
1780  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1781  for (auto i : calibrators) {
1782  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1783  if (calibrator->vehicleTypeExists(vehicleTypeID)) {
1784  return true;
1785  }
1786  }
1787  return false;
1788 }
1789 
1790 
1791 bool
1792 GNENet::flowExists(const std::string& flowID) const {
1793  std::vector<GNEAdditional*> calibrators = getAdditionals(SUMO_TAG_CALIBRATOR);
1794  for (auto i : calibrators) {
1795  GNECalibrator* calibrator = dynamic_cast<GNECalibrator*>(i);
1796  if (calibrator->flowExists(flowID)) {
1797  return true;
1798  }
1799  }
1800  return false;
1801 }
1802 
1803 
1804 bool
1805 GNENet::addPolygon(const std::string& id, const std::string& type, const RGBColor& color, double layer, double angle,
1806  const std::string& imgFile, const PositionVector& shape, bool fill, bool /*ignorePruning*/) {
1807  // check if ID is duplicated
1808  if (myPolygons.get(id) == NULL) {
1809  // create poly
1810  GNEPoly* poly = new GNEPoly(this, id, type, shape, fill, color, layer, angle, imgFile, false, false);
1811  if (myPolygons.add(poly->getID(), poly)) {
1812  myViewNet->getUndoList()->p_begin("add " + toString(poly->getTag()));
1813  myViewNet->getUndoList()->add(new GNEChange_Poly(this, poly, true), true);
1814  myViewNet->getUndoList()->p_end();
1815  return true;
1816  } else {
1817  throw ProcessError("Error adding GNEPOly into shapeContainer");
1818  }
1819  } else {
1820  return false;
1821  }
1822 }
1823 
1824 
1825 GNEPoly*
1827  // generate a ID for myEditJunctionShapePoly
1828  int counter = 0;
1829  std::string polyID = "junction_shape:" + toString(counter);
1830  while (myPolygons.get(polyID) != NULL) {
1831  counter++;
1832  polyID = "junction_shape:" + toString(counter);
1833  }
1834  // obtain shape of NBNode and close it
1835  PositionVector junctionShape = junction->getNBNode()->getShape();
1836  junctionShape.closePolygon();
1837  // create poly for edit shapes
1838  GNEPoly* shapePoly = new GNEPoly(this, "junction_shape:" + toString(counter), "junction_shape", junctionShape, true, RGBColor::GREEN, GLO_POLYGON, 0, "", false , false);
1839  shapePoly->setShapeEditedJunction(junction);
1840  shapePoly->setLineWidth(0.3);
1841  insertPolygonInView(shapePoly);
1842  return shapePoly;
1843 }
1844 
1845 
1846 bool
1847 GNENet::removePolygon(const std::string& id) {
1848  GNEPoly* p = dynamic_cast<GNEPoly*>(myPolygons.get(id));
1849  if (p == 0) {
1850  return false;
1851  } else {
1852  return myPolygons.remove(id);
1853  }
1854 }
1855 
1856 
1857 void
1859  if (p->isShapeVisible() == false) {
1861  myViewNet->update();
1862  p->setShapeVisible(true);
1863  // shapes has to be saved
1865  } else {
1866  throw ProcessError("Polygon was already inserted in view");
1867  }
1868 }
1869 
1870 
1871 void
1873  if (p->isShapeVisible()) {
1875  myViewNet->update();
1876  p->setShapeVisible(false);
1877  // shapes has to be saved
1879  } else {
1880  throw ProcessError("Polygon wasn't already inserted in view");
1881  }
1882 }
1883 
1884 
1885 void
1887  if (p->isShapeVisible()) {
1890  myViewNet->update();
1891  } else {
1892  throw ProcessError("Polygon wasn't inserted in view");
1893  }
1894 }
1895 
1896 
1897 std::string
1899  int counter = 0;
1900  std::string newID = "poly_" + toString(counter);
1901  // generate new IDs to find a non-assigned ID
1902  while (myPolygons.get(newID) != NULL) {
1903  counter++;
1904  newID = "poly_" + toString(counter);
1905  }
1906  return newID;
1907 }
1908 
1909 
1910 GNEPoly*
1911 GNENet::retrievePolygon(const std::string& id, bool failHard) const {
1912  if (myPolygons.get(id) != 0) {
1913  return reinterpret_cast<GNEPoly*>(myPolygons.get(id));
1914  } else if (failHard) {
1915  // If Polygon wasn't found, throw exception
1916  throw UnknownElement("Polygon " + id);
1917  } else {
1918  return NULL;
1919  }
1920 }
1921 
1922 
1923 void
1924 GNENet::changePolygonID(GNEPoly* poly, const std::string& OldID) {
1925  if (myPolygons.get(OldID) == 0) {
1926  throw UnknownElement("Polygon " + OldID);
1927  } else {
1928  myPolygons.changeID(OldID, poly->getID());
1929  }
1930 
1931 }
1932 
1933 
1934 bool
1935 GNENet::addPOI(const std::string& id, const std::string& type, const RGBColor& color, double layer, double angle,
1936  const std::string& imgFile, const Position& pos, double width, double height, bool /*ignorePruning */) {
1937  // check if ID is duplicated
1938  if (myPOIs.get(id) == NULL) {
1939  // create poly
1940  GNEPOI* poi = new GNEPOI(this, id, type, color, layer, angle, imgFile, pos, width, height, false);
1941  if (myPOIs.add(poi->getID(), poi)) {
1942  myViewNet->getUndoList()->p_begin("add " + toString(poi->getTag()));
1943  myViewNet->getUndoList()->add(new GNEChange_POI(this, poi, true), true);
1944  myViewNet->getUndoList()->p_end();
1945  return true;
1946  } else {
1947  throw ProcessError("Error adding GNEPOI into shapeContainer");
1948  }
1949  } else {
1950  return false;
1951  }
1952 }
1953 
1954 
1955 bool
1956 GNENet::removePOI(const std::string& id) {
1957  GNEPOI* p = dynamic_cast<GNEPOI*>(myPOIs.get(id));
1958  if (p == 0) {
1959  return false;
1960  } else {
1961  return myPOIs.remove(id);
1962  }
1963 }
1964 
1965 
1966 void
1968  if (p->isShapeVisible() == false) {
1970  myViewNet->update();
1971  p->setShapeVisible(true);
1972  // shapes has to be saved
1974  } else {
1975  throw ProcessError("POI was already inserted in view");
1976  }
1977 }
1978 
1979 
1980 void
1982  if (p->isShapeVisible()) {
1984  myViewNet->update();
1985  p->setShapeVisible(false);
1986  // shapes has to be saved
1988  } else {
1989  throw ProcessError("POI wasn't already inserted in view");
1990  }
1991 }
1992 
1993 
1994 void
1996  if (p->isShapeVisible()) {
1999  myViewNet->update();
2000  } else {
2001  throw ProcessError("POI wasn't inserted in view");
2002  }
2003 }
2004 
2005 
2006 std::string
2008  int counter = 0;
2009  std::string newID = "POI_" + toString(counter);
2010  // generate new IDs to find a non-assigned ID
2011  while (myPOIs.get(newID) != NULL) {
2012  counter++;
2013  newID = "POI_" + toString(counter);
2014  }
2015  return newID;
2016 }
2017 
2018 
2019 GNEPOI*
2020 GNENet::retrievePOI(const std::string& id, bool failHard) const {
2021  if (myPOIs.get(id) != 0) {
2022  return reinterpret_cast<GNEPOI*>(myPOIs.get(id));
2023  } else if (failHard) {
2024  // If POI wasn't found, throw exception
2025  throw UnknownElement("POI " + id);
2026  } else {
2027  return NULL;
2028  }
2029 }
2030 
2031 
2032 void
2033 GNENet::changePOIID(GNEPOI* POI, const std::string& OldID) {
2034  if (myPOIs.get(OldID) == 0) {
2035  throw UnknownElement("POI " + OldID);
2036  } else {
2037  myPOIs.changeID(OldID, POI->getID());
2038  }
2039 
2040 }
2041 
2042 void GNENet::saveShapes(const std::string& filename) {
2043  // save Shapes
2044  OutputDevice& device = OutputDevice::getDevice(filename);
2045  device.openTag("additionals");
2046  // write only visible polygons
2047  for (auto i : myPolygons.getMyMap()) {
2048  GNEPoly* polygon = dynamic_cast<GNEPoly*>(i.second);
2049  if (polygon->isShapeVisible()) {
2050  polygon->writeShape(device);
2051  }
2052  }
2053  // write only visible POIs
2054  for (auto i : myPOIs.getMyMap()) {
2055  GNEPOI* POI = dynamic_cast<GNEPOI*>(i.second);
2056  if (POI->isShapeVisible()) {
2057  POI->writeShape(device);
2058  }
2059  }
2060  device.close();
2061  // change flag to true
2062  myShapesSaved = true;
2063  // show debug information
2064  if(OptionsCont::getOptions().getBool("gui-testing-debug")) {
2065  WRITE_WARNING("Shapes saved");
2066  }
2067 }
2068 
2069 
2070 int
2072  return (int)(myPolygons.size() + myPOIs.size());
2073 }
2074 
2075 
2076 bool
2077 GNENet::isShapeSelected(SumoXMLTag tag, const std::string& ID) const {
2078  if (tag == SUMO_TAG_POLY) {
2080  } else if (tag == SUMO_TAG_POI) {
2082  } else {
2083  throw ProcessError("Invalid Shape");
2084  }
2085 }
2086 
2087 
2088 // ===========================================================================
2089 // private
2090 // ===========================================================================
2091 
2092 void
2094  // init junctions (by default Crossing and walking areas aren't created)
2095  NBNodeCont& nodeContainer = myNetBuilder->getNodeCont();
2096  for (auto name_it : nodeContainer.getAllNames()) {
2097  NBNode* nbn = nodeContainer.retrieve(name_it);
2098  registerJunction(new GNEJunction(*nbn, this, true));
2099  }
2100 
2101  // init edges
2103  for (auto name_it : ec.getAllNames()) {
2104  NBEdge* nbe = ec.retrieve(name_it);
2105  registerEdge(new GNEEdge(*nbe, this, false, true));
2106  if (myGrid.getWidth() > 10e16 || myGrid.getHeight() > 10e16) {
2107  throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
2108  }
2109  }
2110 
2111  // make sure myGrid is initialized even for an empty net
2112  if (myEdges.size() == 0) {
2113  myGrid.add(Boundary(0, 0, 100, 100));
2114  }
2115 
2116  // sort nodes edges so that arrows can be drawn correctly
2117  NBNodesEdgesSorter::sortNodesEdges(nodeContainer);
2118 }
2119 
2120 
2121 void
2123  myNetBuilder->getNodeCont().insert(junction->getNBNode());
2124  registerJunction(junction);
2125 }
2126 
2127 
2128 void
2130  NBEdge* nbe = edge->getNBEdge();
2131  myNetBuilder->getEdgeCont().insert(nbe); // should we ignore pruning double edges?
2132  // if this edge was previouls extracted from the edgeContainer we have to rewire the nodes
2133  nbe->getFromNode()->addOutgoingEdge(nbe);
2134  nbe->getToNode()->addIncomingEdge(nbe);
2135  registerEdge(edge);
2136 }
2137 
2138 
2139 GNEJunction*
2141  junction->incRef("GNENet::registerJunction");
2142  junction->setResponsible(false);
2143  myJunctions[junction->getMicrosimID()] = junction;
2144  myGrid.add(junction->getBoundary());
2145  myGrid.addAdditionalGLObject(junction);
2146  // @todo let Boundary class track z-coordinate natively
2147  const double z = junction->getNBNode()->getPosition().z();
2148  if (z != 0) {
2150  }
2151  update();
2152  return junction;
2153 }
2154 
2155 
2156 GNEEdge*
2158  edge->incRef("GNENet::registerEdge");
2159  edge->setResponsible(false);
2160  // add edge to internal container of GNENet
2161  myEdges[edge->getMicrosimID()] = edge;
2162  // add edge to grid
2163  myGrid.add(edge->getBoundary());
2165  // Add references into GNEJunctions
2168  // update view
2169  update();
2170  return edge;
2171 }
2172 
2173 
2174 void
2176  myGrid.removeAdditionalGLObject(junction);
2177  myJunctions.erase(junction->getMicrosimID());
2178  myNetBuilder->getNodeCont().extract(junction->getNBNode());
2179  junction->decRef("GNENet::deleteSingleJunction");
2180  junction->setResponsible(true);
2181  // selection status is lost when removing junction via undo and the selection operation was not part of a command group
2182  gSelected.deselect(junction->getGlID());
2183  update();
2184 }
2185 
2186 
2187 void
2189  // remove edge from visual grid and container
2191  myEdges.erase(edge->getMicrosimID());
2192  // extract edge of district container
2194  edge->decRef("GNENet::deleteSingleEdge");
2195  edge->setResponsible(true);
2196  // selection status is lost when removing edge via undo and the selection operation was not part of a command group
2197  gSelected.deselect(edge->getGlID());
2198  // Remove refrences from GNEJunctions
2201  // invalidate junction logic
2202  update();
2203 }
2204 
2205 
2206 void
2208  if (myViewNet) {
2209  myViewNet->update();
2210  }
2211 }
2212 
2213 
2214 void
2215 GNENet::reserveEdgeID(const std::string& id) {
2216  myEdgeIDSupplier.avoid(id);
2217 }
2218 
2219 
2220 void
2221 GNENet::reserveJunctionID(const std::string& id) {
2223 }
2224 
2225 
2226 void
2228  for (auto it : myEdges) {
2229  it.second->remakeGNEConnections();
2230  }
2231  for (auto it : myEdges) {
2232  it.second->updateGeometry();
2233  }
2234 }
2235 
2236 
2237 void
2238 GNENet::computeAndUpdate(OptionsCont& oc, bool volatileOptions) {
2239  // make sure we only add turn arounds to edges which currently exist within the network
2240  std::set<std::string> liveExplicitTurnarounds;
2241  for (auto it : myExplicitTurnarounds) {
2242  if (myEdges.count(it) > 0) {
2243  liveExplicitTurnarounds.insert(it);
2244  }
2245  }
2246  myNetBuilder->compute(oc, liveExplicitTurnarounds, volatileOptions);
2247  // update ids if necessary
2248  if (oc.getBool("numerical-ids") || oc.isSet("reserved-ids")) {
2249  GNEEdges newEdgeMap;
2250  GNEJunctions newJunctionMap;
2251  // fill newEdgeMap
2252  for (auto it : myEdges) {
2253  it.second->setMicrosimID(it.second->getNBEdge()->getID());
2254  newEdgeMap[it.second->getNBEdge()->getID()] = it.second;
2255  }
2256  for (auto it : myJunctions) {
2257  newJunctionMap[it.second->getNBNode()->getID()] = it.second;
2258  it.second->setMicrosimID(it.second->getNBNode()->getID());
2259  }
2260  myEdges = newEdgeMap;
2261  myJunctions = newJunctionMap;
2262  }
2263  // update rtree if necessary
2264  if (!oc.getBool("offset.disable-normalization")) {
2265  for (auto it : myEdges) {
2266  refreshElement(it.second);
2267  }
2268  }
2269  myGrid.reset();
2270  myGrid.add(GeoConvHelper::getFinal().getConvBoundary());
2271  // if volatile options are true
2272  if (volatileOptions) {
2273  // clear all Polys of grid
2274  for (auto i : myPolygons.getMyMap()) {
2275  GNEPoly* polygon = dynamic_cast<GNEPoly*>(i.second);
2276  if (polygon->isShapeVisible()) {
2277  removePolygonOfView(polygon);
2278  }
2279  }
2280 
2281  // clear all POIs of grid
2282  for (auto i : myPOIs.getMyMap()) {
2283  GNEPOI* POI = dynamic_cast<GNEPOI*>(i.second);
2284  if (POI->isShapeVisible()) {
2285  removePOIOfView(POI);
2286  }
2287  }
2288 
2289  // clear all additionals of grid
2290  GNEAdditionals copyOfAdditionals = myAdditionals;
2291  for (auto it : copyOfAdditionals) {
2292  myGrid.removeAdditionalGLObject(it.second);
2293  }
2294 
2295  // remove all edges of grid and net
2296  GNEEdges copyOfEdges = myEdges;
2297  for (auto it : copyOfEdges) {
2298  myGrid.removeAdditionalGLObject(it.second);
2299  myEdges.erase(it.second->getMicrosimID());
2300  }
2301 
2302  // removes all junctions of grid and net
2303  GNEJunctions copyOfJunctions = myJunctions;
2304  for (auto it : copyOfJunctions) {
2305  myGrid.removeAdditionalGLObject(it.second);
2306  myJunctions.erase(it.second->getMicrosimID());
2307  }
2308 
2309  // clear undo list
2310  myViewNet->getUndoList()->clear();
2311 
2312  // clear additionals (must be do it separated)
2313  myAdditionals.clear();
2314 
2315  // init again junction an edges
2317  }
2318 
2319  // update precomputed geometries
2321 
2322  for (auto it : myJunctions) {
2323  it.second->setLogicValid(true);
2324  // updated shape
2325  it.second->updateGeometry();
2326  refreshElement(it.second);
2327  }
2328 
2329  myNeedRecompute = false;
2330 }
2331 
2332 
2333 void
2334 GNENet::replaceInListAttribute(GNEAttributeCarrier* ac, SumoXMLAttr key, const std::string& which, const std::string& by, GNEUndoList* undoList) {
2335  assert(GNEAttributeCarrier::isList(ac->getTag(), key));
2336  std::vector<std::string> values = GNEAttributeCarrier::parse<std::vector<std::string> >(ac->getAttribute(key));
2337  std::vector<std::string> newValues;
2338  for (auto v : values) {
2339  newValues.push_back(v == which ? by : v);
2340  }
2341  ac->setAttribute(key, toString(newValues), undoList);
2342 }
2343 
2344 /****************************************************************************/
void setViewNet(GNEViewNet *viewNet)
Set the viewNet to be notified of network changes.
Definition: GNENet.cpp:880
GNEJunction * splitEdge(GNEEdge *edge, const Position &pos, GNEUndoList *undoList, GNEJunction *newJunction=0)
split edge at position by inserting a new junction
Definition: GNENet.cpp:637
std::vector< GNEJunction * > retrieveJunctions(bool onlySelected=false)
return all junctions
Definition: GNENet.cpp:978
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNENet.cpp:169
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
std::string getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a &#39; &#39;.
void initJunctionsAndEdges()
Init Junctions and edges.
Definition: GNENet.cpp:2093
a tl-logic
double z() const
Returns the z-position.
Definition: Position.h:73
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:243
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:944
bool areStoppingPlacesPositionsFixed() const
check if Position of stoppingPlace are fixed
void close()
Closes the device and removes it from the dictionary.
GNEViewNet * myViewNet
The viewNet to be notofied of about changes.
Definition: GNENet.h:671
SumoXMLTag
Numbers representing SUMO-XML - element names.
void requiereSaveAdditionals()
inform that additionals has to be saved
Definition: GNENet.cpp:1237
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
the function-object for an editing operation (abstract base)
Definition: GNEChange.h:49
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
void enableSaveAdditionalsMenu()
enable save additionals
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true)
get edge by id
Definition: GNENet.cpp:899
bool flowExists(std::string flowID) const
check if a flow with ID = flowID exists
IDSupplier myEdgeIDSupplier
Definition: GNENet.h:694
description of a vehicle type
GNEJunction * getGNEJunctionSource() const
returns the source-junction
Definition: GNEEdge.cpp:194
bool flowExists(const std::string &flowID) const
Check if exist a flow with these ID.
Definition: GNENet.cpp:1792
void removePolygonOfView(GNEPoly *p)
remove polygon of view net
Definition: GNENet.cpp:1872
void setStatusBarText(const std::string &statusBarText)
set text of the statusBar
is a pedestrian
a polygon
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
Definition: NBEdgeCont.cpp:542
void append(const PositionVector &v, double sameThreshold=2.0)
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
SUMORTree myGrid
the rtree which contains all GUIGlObjects (so named for historical reasons)
Definition: GNENet.h:668
void deletePOI(GNEPOI *POI, GNEUndoList *undoList)
remove POI
Definition: GNENet.cpp:514
GUIGlObjectType
begin/end of the description of a junction
begin/end of the description of a single lane
FXApp * getApp()
get pointer to the main App
Definition: GNENet.cpp:1268
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
bool removePolygon(const std::string &id)
Removes a polygon from the container.
Definition: GNENet.cpp:1847
GNEPoly * addPolygonForEditShapes(GNEJunction *junction)
Builds a special polygon used for edit Junctions&#39;s shapes.
Definition: GNENet.cpp:1826
void refreshElement(GUIGlObject *o)
refreshes boundary information for o and update
Definition: GNENet.cpp:990
void enableSaveShapesMenu()
enable save shapes
GNEAdditionals myAdditionals
map with the name and pointer to additional elements of net
Definition: GNENet.h:690
The main window of the Netedit.
bool changeID(const std::string &oldId, const std::string &newId)
change ID of a stored object
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:1176
virtual bool add(const std::string &id, T item)
Adds an item.
bool revertLaneRestriction(GNELane *lane, GNEUndoList *undoList)
revert prevously restricted lane
Definition: GNENet.cpp:582
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
std::string generatePOIID() const
generate a POI ID
Definition: GNENet.cpp:2007
A container for traffic light definitions and built programs.
void refreshPOI(GNEPOI *p)
refresh shape in view net
Definition: GNENet.cpp:1995
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
Definition: NBEdge.cpp:2898
void setLogicValid(bool valid, GNEUndoList *undoList=0, const std::string &status=GUESSED)
double x() const
Returns the x-position.
Definition: Position.h:63
Definition: GNEPOI.h:52
connectio between two lanes
Stores the information about how to visualize structures.
std::set< GUIGlID > getGlIDs(GUIGlObjectType type=GLO_MAX)
get ids of currently active objects
Definition: GNENet.cpp:1070
a connection
vehicle is a bicycle
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition: GNELane.cpp:764
bool addPOI(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, const Position &pos, double width, double height, bool ignorePruning=false)
Builds a POI using the given values and adds it to the container.
Definition: GNENet.cpp:1935
bool vehicleTypeExists(const std::string &vehicleTypeID) const
Check if exist a vehicle type with these ID.
Definition: GNENet.cpp:1779
void select(GUIGlID id, bool update=true)
Adds the object with the given id.
const std::vector< GNEAdditional * > & getAdditionalChilds() const
get additional childs of lane
Definition: GNELane.cpp:758
void addIncomingEdge(NBEdge *edge)
adds an incoming edge
Definition: NBNode.cpp:402
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:71
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
Definition: NBEdge.cpp:376
POIs myPOIs
stored POIs
Polygons myPolygons
stored Polygons
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNENet.cpp:190
static void writeJoinedJunctions(const OptionsCont &oc, NBNodeCont &nc)
Writes the joined-juncionts to file.
std::vector< GNELane * > LaneVector
Definition of the lane&#39;s vector.
Definition: GNEEdge.h:66
void removeAdditionalGLObject(GUIGlObject *o)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition: SUMORTree.h:141
NBNode * getNBNode() const
Return net build node.
void avoid(const std::string &id)
make sure that the given id is never supplied
Definition: IDSupplier.cpp:67
void reverseEdge(GNEEdge *edge, GNEUndoList *undoList)
reverse edge
Definition: GNENet.cpp:700
void update()
notify myViewNet
Definition: GNENet.cpp:2207
void insertJunction(GNEJunction *junction)
inserts a single junction into the net and into the underlying netbuild-container ...
Definition: GNENet.cpp:2122
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:259
void saveAdditionals(const std::string &filename, bool volatileOptionsEnabled=false)
save additional elements of the network
Definition: GNENet.cpp:813
bool routeExists(const std::string &routeID) const
Check if exist a route with these ID.
Definition: GNENet.cpp:1766
std::string getAttribute(SumoXMLAttr key) const
This functions has to be implemented in allGNEAttributeCarrier.
Definition: GNEEdge.cpp:617
void deleteConnection(GNEConnection *connection, GNEUndoList *undoList)
remove connection
Definition: GNENet.cpp:478
void splitEdgesBidi(const std::set< GNEEdge * > &edges, const Position &pos, GNEUndoList *undoList)
split all edges at position by inserting one new junction
Definition: GNENet.cpp:689
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:92
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:54
GNEEdge * createEdge(GNEJunction *src, GNEJunction *dest, GNEEdge *tpl, GNEUndoList *undoList, const std::string &suggestedName="", bool wasSplit=false, bool allowDuplicateGeom=false)
creates a new edge (unless an edge with the same geometry already exists)
Definition: GNENet.cpp:225
void p_begin(const std::string &description)
Begin undo command sub-group. This begins a new group of commands that are treated as a single comman...
Definition: GNEUndoList.cpp:85
bool routeExists(std::string routeID) const
check if a route with ID = routeID exists
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition: GNENet.cpp:1540
void rename(NBEdge *edge, const std::string &newID)
Renames the edge. Throws exception if newID already exists.
Definition: NBEdgeCont.cpp:404
bool cleanInvalidCrossings(GNEUndoList *undoList)
clear invalid crossings
Definition: GNENet.cpp:1387
Storage for geometrical objects.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
begin/end of the description of a polygon
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:513
GNEEdge * getEdgeFrom() const
get the name of the edge the vehicles leave
void insertEdge(GNEEdge *edge)
inserts a single edge into the net and into the underlying netbuild-container
Definition: GNENet.cpp:2129
const std::vector< GNEAdditional * > & getAdditionalChilds() const
return list of additionals associated with this edge
Definition: GNEEdge.cpp:1212
bool checkIsRemovable() const
check if node is removable
Definition: NBNode.cpp:1634
const std::vector< GNEEdge * > & getGNEEdges() const
Returns all GNEEdges vinculated with this Junction.
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
void setLineWidth(double lineWidth)
set a new shape and update the tesselation
Definition: GUIPolygon.h:116
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1161
GNEViewParent * getViewParent() const
get the net object
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList)
removes edge
Definition: GNENet.cpp:332
virtual bool isDetectorPositionFixed() const =0
check if Position of detector is fixed
bool vehicleTypeExists(std::string vehicleTypeID) const
check if a vehicelType with ID = vehicleTypeID exists
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:110
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node&#39;s edges clockwise regarding driving direction.
A RT-tree for efficient storing of SUMO&#39;s GL-objects.
Definition: SUMORTree.h:74
first coordinate of edge shape
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
Definition: NBNode.cpp:412
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:701
void remapEdge(GNEEdge *oldEdge, GNEJunction *from, GNEJunction *to, GNEUndoList *undoList, bool keepEndpoints=false)
Definition: GNENet.cpp:770
GUIGlID getGlID() const
Returns the numerical id of the object.
GNEJunction * registerJunction(GNEJunction *junction)
registers a junction with GNENet containers
Definition: GNENet.cpp:2140
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:256
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
bool myNeedRecompute
whether the net needs recomputation
Definition: GNENet.h:702
Builds trigger objects for GNENet (busStops, chargingStations, detectors, etc..)
int getNumberOfAdditionals(SumoXMLTag type=SUMO_TAG_NOTHING) const
Returns the number of additionals of the net.
Definition: GNENet.cpp:1715
NBNetBuilder * myNetBuilder
The internal netbuilder.
Definition: GNENet.h:674
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
void setNetObject(GUIGlObject *object)
Sets the given object as the "network" object.
const Boundary & getBoundary() const
returns the bounder of the network
Definition: GNENet.cpp:162
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
GNEUndoList * getUndoList() const
get the undoList object
bool priority
whether the pedestrians have priority
Definition: NBNode.h:160
PositionVector reverse() const
reverse position vector
bool restrictLane(SUMOVehicleClass vclass, GNELane *lane, GNEUndoList *undoList)
transform lane to restricted lane
Definition: GNENet.cpp:556
T get(const std::string &id) const
Retrieves an item.
bool myAdditionalsSaved
Flag to check if additionals has to be saved.
Definition: GNENet.h:705
void renameJunction(GNEJunction *junction, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1531
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
NBConnection getNBConnection() const
get NBConnection
void p_add(GNEChange_Attribute *cmd)
special method, avoid empty changes, always execute
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:248
IDSupplier myJunctionIDSupplier
Definition: GNENet.h:695
An (internal) definition of a single lane of an edge.
Definition: NBEdge.h:122
const std::string & getID() const
Returns the id.
Definition: Named.h:66
the function-object for an editing operation (abstract base)
void refreshPolygon(GNEPoly *p)
refresh polygon in view net
Definition: GNENet.cpp:1886
void changePOIID(GNEPOI *POI, const std::string &OldID)
change POI ID
Definition: GNENet.cpp:2033
static const double Z_INITIALIZED
marker for whether the z-boundary is initialized
Definition: GNENet.h:755
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
const std::vector< GNERerouter * > & getGNERerouters() const
get rerouters vinculated with this edge
Definition: GNEEdge.cpp:1239
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:494
friend class GNEChange_Connection
Definition: GNENet.h:97
const Position & getPosition() const
Definition: NBNode.h:235
static const RGBColor GREEN
Definition: RGBColor.h:180
std::string getAdditionalID(SumoXMLTag type, const GNELane *lane, const double pos) const
Returns the additional close to the given position.
Definition: GNENet.cpp:1692
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:162
const std::set< GUIGlID > & getSelected() const
Returns the set of ids of all selected objects.
void updateAdditionalID(const std::string &oldID, GNEAdditional *additional)
update additional ID in container
Definition: GNENet.cpp:1638
std::string getNext()
Returns the next id.
Definition: IDSupplier.cpp:59
bool removeRestrictedLane(SUMOVehicleClass vclass, GNEEdge &edge, GNEUndoList *undoList)
remove restricted lane
Definition: GNENet.cpp:615
std::map< std::string, GNEJunction * > GNEJunctions
Definition: GNENet.h:678
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:296
the edges of a route
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:158
const GNECalibratorRoute & getCalibratorRoute(const std::string &routeID)
get reference calibrator route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition: GNECrossing.h:52
GNEEdge & getParentEdge()
Returns underlying parent edge.
Definition: GNELane.cpp:1085
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNELane.cpp:811
void moveJunctionGeometry(Position pos)
reposition the node at pos and informs the edges
void insertPolygonInView(GNEPoly *p)
insert created polygon in view net
Definition: GNENet.cpp:1858
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GNENet.cpp:179
void refreshAdditional(GNEAdditional *additional)
refreshes boundary information of an additional after a geometry update
Definition: GNENet.cpp:998
void writeShape(OutputDevice &device)
writte shape element into a xml file
Definition: GNEPoly.cpp:164
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:168
void extract(NBDistrictCont &dc, NBEdge *edge, bool remember=false)
Removes the given edge from the container like erase but does not delete it.
Definition: NBEdgeCont.cpp:392
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
void p_end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise, the sub-group will be added as a new command into parent group. A matching begin() must have been called previously.
Definition: GNEUndoList.cpp:92
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
GNEJunction * retrieveJunction(const std::string &id, bool failHard=true)
get junction by id
Definition: GNENet.cpp:886
void setx(double x)
set position x
Definition: Position.h:78
GNEJunctions myJunctions
map with the name and pointer to junctions of net
Definition: GNENet.h:684
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:156
A list of positions.
GNELane * retrieveLane(const std::string &id, bool failHard=true)
get lane by id
Definition: GNENet.cpp:958
bool joinSelectedJunctions(GNEUndoList *undoList)
join selected junctions
Definition: GNENet.cpp:1280
Boundary myZBoundary
the z boundary (stored in the x-coordinate), values of 0 are ignored
Definition: GNENet.h:752
void setShapeVisible(bool visible)
set flag to enable or disable if shape is visible
Definition: GNEShape.cpp:81
void deleteLane(GNELane *lane, GNEUndoList *undoList)
removes lane
Definition: GNENet.cpp:436
void replaceIncomingEdge(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replaces edge
Definition: GNENet.cpp:383
void deleteGeometryOrEdge(GNEEdge *edge, const Position &pos, GNEUndoList *undoList)
removes geometry when pos is close to a geometry node, deletes the whole edge otherwise ...
Definition: GNENet.cpp:629
bool isShapeSelected(SumoXMLTag tag, const std::string &ID) const
Check if shape item is selected.
Definition: GNENet.cpp:2077
virtual bool remove(const std::string &id)
Removes an item.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
a tl-logic
Boundary getBoundary() const
Returns the street&#39;s geometry.
Definition: GNEEdge.cpp:163
double y() const
Returns the y-position.
Definition: Position.h:68
void changePolygonID(GNEPoly *poly, const std::string &OldID)
change Polygon ID
Definition: GNENet.cpp:1924
GNEPoly * retrievePolygon(const std::string &id, bool failHard=true) const
get Polygon by id
Definition: GNENet.cpp:1911
void commitGeometryMoving(const Position &oldPos, GNEUndoList *undoList)
registers completed movement with the undoList
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:414
void computeJunction(GNEJunction *junction)
trigger recomputation of junction shape and logic param[in] window The window to inform about delay ...
Definition: GNENet.cpp:1216
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:253
const GNECalibratorFlow & getGNECalibratorFlow(const std::string &calibratorFlowID) const
Returns a reference to a calibrator flow finding in all calibrators of net.
Definition: GNENet.cpp:1753
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
GNEJunction * getParentJunction() const
get parent Junction
Definition: GNECrossing.cpp:94
void initGNEConnections()
initialize GNEConnections
Definition: GNENet.cpp:2227
#define POSITION_EPS
Definition: config.h:176
const GNECalibratorVehicleType & getCalibratorVehicleType(const std::string &vehicleTypeID)
get reference to calibrator vehicle type
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into XML-files (nodes, edges, connections, traffic lights)
void save(OptionsCont &oc)
save the network
Definition: GNENet.cpp:804
edge: the shape in xml-definition
std::string generatePolyID() const
generate PolyID
Definition: GNENet.cpp:1898
std::vector< GNEAttributeCarrier * > retrieveAttributeCarriers(const std::set< GUIGlID > &ids, GUIGlObjectType type)
get the attribute carriers based on GlIDs
Definition: GNENet.cpp:1020
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:498
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
std::vector< std::string > getAllNames() const
get all node names
void insertPOIInView(GNEPOI *p)
insert created shape in view net
Definition: GNENet.cpp:1967
friend class GNEChange_Edge
Definition: GNENet.h:96
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
const std::string getID() const
function to support debugging
void moveSelection(const Position &moveSrc, const Position &moveDest)
move all selected junctions and edges
Definition: GNENet.cpp:1552
GNEJunction * createJunction(const Position &pos, GNEUndoList *undoList)
creates a new junction
Definition: GNENet.cpp:214
void incRef(const std::string &debugMsg="")
Increarse reference.
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:1726
void move2side(double amount)
move position vector to side using certain ammount
SUMORTree & getVisualisationSpeedUp()
Returns the RTree used for visualisation speed-up.
Definition: GNENet.cpp:202
std::set< std::string > myExplicitTurnarounds
list of edge ids for which turn-arounds must be added explicitly
Definition: GNENet.h:699
void decRef(const std::string &debugMsg="")
Decrease reference.
bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, const PositionVector &shape, bool fill, bool ignorePruning=false)
Builds a polygon using the given values and adds it to the container.
Definition: GNENet.cpp:1805
void rename(NBNode *node, const std::string &newID)
Renames the node. Throws exception if newID already exists.
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection)
std::vector< GNECrossing * > getGNECrossings()
get GNECrossings vinculated with this Edge
Definition: GNEEdge.cpp:550
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
Definition: NBNode.cpp:1703
begin/end of the description of an edge
NBNode::Crossing * getNBCrossing() const
get referente to NBode::Crossing
std::vector< GNEAdditional * > getAdditionals(SumoXMLTag type=SUMO_TAG_NOTHING) const
get vector with additionals
Definition: GNENet.cpp:1703
const GNECalibratorRoute & getGNECalibratorRoute(const std::string &calibratorRouteID) const
Returns a reference to a calibrator route finding in all calibrators of net.
Definition: GNENet.cpp:1727
NBEdge::Connection & getNBEdgeConnection() const
get Edge::Connection
bool checkJunctionPosition(const Position &pos)
return true if there are already a Junction in the given position, false in other case ...
Definition: GNENet.cpp:792
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network stored in the given net builder.
Definition: NWFrame.cpp:161
const IDMap & getMyMap() const
Returns a reference to the internal map.
void replaceJunctionByGeometry(GNEJunction *junction, GNEUndoList *undoList)
replace the selected junction by geometry node(s) and merge the edges
Definition: GNENet.cpp:1460
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:58
void reserveJunctionID(const std::string &id)
reserve junction ID (To avoid duplicates)
Definition: GNENet.cpp:2221
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2988
compound additional
vehicle is a bus
GNEAdditional * getAdditional(SumoXMLTag type, const std::string &id) const
Returns the named additional.
Definition: GNENet.cpp:1680
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNENet.cpp:185
void reset()
Resets the boundary.
Definition: Boundary.cpp:74
void setResponsible(bool newVal)
set responsibility for deleting internal strctures
Definition: GNEEdge.cpp:885
void deletePolygon(GNEPoly *polygon, GNEUndoList *undoList)
remove Polygon
Definition: GNENet.cpp:529
void deleteSingleJunction(GNEJunction *junction)
deletes a single junction
Definition: GNENet.cpp:2175
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:435
double width
This lane&#39;s width.
Definition: NBNode.h:152
~GNENet()
Destructor.
Definition: GNENet.cpp:132
const Boundary & getZBoundary() const
Returns the Z boundary (stored in the x() coordinate) values of 0 do not affect the boundary...
Definition: GNENet.cpp:196
void deselect(GUIGlID id)
Deselects the object with the given id.
const std::vector< GNELane * > & getLanes()
returns a reference to the lane vector
Definition: GNEEdge.cpp:599
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
bool deleteGeometry(const Position &pos, GNEUndoList *undoList)
deletes the closest geometry node within SNAP_RADIUS.
Definition: GNEEdge.cpp:394
std::vector< GNEEdge * > retrieveEdges(bool onlySelected=false)
return all edges
Definition: GNENet.cpp:932
GNEEdge * registerEdge(GNEEdge *edge)
registers an edge with GNENet containers
Definition: GNENet.cpp:2157
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:161
void addAdditionalGLObject(GUIGlObject *o)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition: SUMORTree.h:129
bool computeSingleLogic(OptionsCont &oc, NBTrafficLightDefinition *def)
Computes a specific traffic light logic (using by NETEDIT)
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:62
Boundary getBoundary() const
Returns the boundary of the junction.
Instance responsible for building networks.
Definition: NBNetBuilder.h:115
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
friend class GNEChange_Junction
declare friend class
Definition: GNENet.h:95
virtual std::string getAttribute(SumoXMLAttr key) const =0
This functions has to be implemented in allGNEAttributeCarrier.
void removeSolitaryJunctions(GNEUndoList *undoList)
removes junctions that have no edges
Definition: GNENet.cpp:1443
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:41
void analyzeCluster(std::set< NBNode * > cluster, std::string &id, Position &pos, bool &hasTLS, TrafficLightType &type)
Definition: NBNodeCont.cpp:827
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:596
void sety(double y)
set position y
Definition: Position.h:83
A storage for options typed value containers)
Definition: OptionsCont.h:99
The popup menu of a globject.
an edge
bool removePOI(const std::string &id)
Removes a PoI from the container.
Definition: GNENet.cpp:1956
class for GNEChange_ReplaceEdgeInTLS
Definition: GNENet.h:758
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:77
void computeEverything(GNEApplicationWindow *window, bool force=false, bool volatileOptions=false, std::string additionalPath="", std::string shapePath="")
trigger full netbuild computation param[in] window The window to inform about delay param[in] force W...
Definition: GNENet.cpp:1167
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:171
void computeAndUpdate(OptionsCont &oc, bool volatileOptions)
recompute the network and update lane geometries
Definition: GNENet.cpp:2238
crossing between edges for pedestrians
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1496
static void replaceInListAttribute(GNEAttributeCarrier *ac, SumoXMLAttr key, const std::string &which, const std::string &by, GNEUndoList *undoList)
Definition: GNENet.cpp:2334
void resetLastTag()
reset last Tag and clear non-valid Additionals (For example, created E3 withouts Entry/Exit childs) ...
GNENet * getNet() const
get the net object
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
vaporizer of vehicles
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition: GNENet.cpp:280
bool netHasGNECrossings() const
check if net has GNECrossings
Definition: GNENet.cpp:1257
The network - empty.
std::string generateVaporizerID() const
generate an ID for vaporizers
Definition: GNENet.cpp:1010
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:678
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:1546
EdgeVector edges
The edges being crossed.
Definition: NBNode.h:148
Represents a single node (junction) during network building.
Definition: NBNode.h:75
void saveJoined(OptionsCont &oc)
save log of joined junctions (and nothing else)
Definition: GNENet.cpp:872
std::vector< GNEAdditional * > retrieveAdditionals(bool onlySelected=false)
return all additionals
Definition: GNENet.cpp:1668
void deleteAdditional(GNEAdditional *additional)
delete additional element previously inserted
Definition: GNENet.cpp:1622
void writeShape(OutputDevice &device)
writte shape element into a xml file
Definition: GNEPOI.cpp:78
SumoXMLTag getTag() const
get XML Tag assigned to this object
GNEEdge * addReversedEdge(GNEEdge *edge, GNEUndoList *undoList)
add reversed edge
Definition: GNENet.cpp:711
void requiereSaveShapes()
inform that shapes has to be saved
Definition: GNENet.cpp:1247
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
GNEPOI * retrievePOI(const std::string &id, bool failHard=true) const
get POI by id
Definition: GNENet.cpp:2020
GNEEdges myEdges
map with the name and pointer to edges of net
Definition: GNENet.h:687
bool isShapeVisible() const
check if shape is visible (Was added into view using insertPolygon/POIInView)
Definition: GNEShape.cpp:75
last coordinate of edge shape
std::pair< PositionVector, PositionVector > splitAt(double where) const
Returns the two lists made when this list vector is splitted at the given point.
std::map< std::pair< std::string, SumoXMLTag >, GNEAdditional * > GNEAdditionals
Definition: GNENet.h:680
void removePOIOfView(GNEPOI *p)
remove shape of view net
Definition: GNENet.cpp:1981
void push_back_noDoublePos(const Position &p)
insert in back a non double position
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2746
empty max
void unblockObject(GUIGlID id)
Marks an object as unblocked.
const GNECalibratorVehicleType & getGNECalibratorVehicleType(const std::string &calibratorVehicleTypeID) const
Returns a reference to a calibrator vehicle type finding in all calibrators of net.
Definition: GNENet.cpp:1740
void setShapeEditedJunction(GNEJunction *junction)
retrieve the junction of which the shape is being edited
Definition: GNEPoly.cpp:336
void reserveEdgeID(const std::string &id)
reserve edge ID (To avoid duplicates)
Definition: GNENet.cpp:2215
void compute(OptionsCont &oc, const std::set< std::string > &explicitTurnarounds=std::set< std::string >(), bool mayAddOrRemove=true)
Performs the network building steps.
void deleteSingleEdge(GNEEdge *edge)
deletes a single edge
Definition: GNENet.cpp:2188
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:106
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
std::map< std::string, GNEEdge * > GNEEdges
Definition: GNENet.h:679
NBEdge * getNBEdge()
returns the internal NBEdge
Definition: GNEEdge.cpp:306
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
GNEAdditional * retrieveAdditional(const std::string &idl, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:1653
void mergeJunctions(GNEJunction *moved, GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition: GNENet.cpp:745
bool extract(NBNode *node, bool remember=false)
Removes the given node but does not delete it.
Definition: NBNodeCont.cpp:147
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
static std::string getEdgeIDFromLane(const std::string laneID)
return edge id when given the lane ID
void insertAdditional(GNEAdditional *additional, bool hardFail=true)
Insert a additional element previously created in GNEAdditionalHandler.
Definition: GNENet.cpp:1604
const GNECalibratorFlow & getCalibratorFlow(const std::string &flowID)
get reference to calibrator flow
int getNumberOfShapes() const
get number of shapes
Definition: GNENet.cpp:2071
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:176
void closePolygon()
ensures that the last position equals the first
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:693
bool addSRestrictedLane(SUMOVehicleClass vclass, GNEEdge &edge, GNEUndoList *undoList)
add restricted lane to edge
Definition: GNENet.cpp:600
GUISelectedStorage gSelected
A global holder of selected objects.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:835
bool myShapesSaved
Flag to check if shapes hast o be saved.
Definition: GNENet.h:708
A window containing a gl-object&#39;s parameter.
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:1509
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1525
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1519
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:611
void savePlain(OptionsCont &oc)
save plain xml representation of the network (and nothing else)
Definition: GNENet.cpp:864
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:237
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1232
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void duplicateLane(GNELane *lane, GNEUndoList *undoList)
duplicates lane
Definition: GNENet.cpp:544
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
TrafficLightType
static bool isList(SumoXMLTag tag, SumoXMLAttr attr)
whether an attribute is of type bool
begin/end of the description of a polygon
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
void saveShapes(const std::string &filename)
save shapes elements of the network
Definition: GNENet.cpp:2042
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void registerJoinedCluster(const std::set< NBNode * > &cluster)
gets all joined clusters (see doc for myClusters2Join)
Definition: NBNodeCont.cpp:817
a junction
GNEJunction * getGNEJunctionDestiny() const
returns the destination-junction
Definition: GNEEdge.cpp:200
int size() const
Returns the number of stored items within the container.
void finishMoveSelection(GNEUndoList *undoList)
register changes to junction and edge positions with the undoList
Definition: GNENet.cpp:1582
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:428
NBNetBuilder * getNetBuilder() const
get net builder
Definition: GNENet.cpp:1274