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