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