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