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
647 GNENet::addRestrictedLane(SUMOVehicleClass vclass, GNEEdge& edge, int index, GNEUndoList* undoList) {
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  // check that index is correct
655  if (index >= (int)edge.getLanes().size()) {
656  return false;
657  }
658  // duplicate selected lane
659  duplicateLane(edge.getLanes().at(index), undoList, true);
660  // transform the created (last) lane to a sidewalk
661  return restrictLane(vclass, edge.getLanes().at(index), undoList);
662 }
663 
664 
665 bool
667  // iterate over lanes of edge
668  for (auto i : edge.getLanes()) {
669  if (i->isRestricted(vclass)) {
670  // Delete lane
671  deleteLane(i, undoList, true);
672  return true;
673  }
674  }
675  return false;
676 }
677 
678 
680 GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
681  undoList->p_begin("split " + toString(SUMO_TAG_EDGE));
682  if (newJunction == 0) {
683  newJunction = createJunction(pos, undoList);
684  }
685  // compute geometry
686  const PositionVector& oldGeom = edge->getNBEdge()->getGeometry();
687  const double linePos = oldGeom.nearest_offset_to_point2D(pos, false);
688  std::pair<PositionVector, PositionVector> newGeoms = oldGeom.splitAt(linePos);
689  const std::string shapeEnd = edge->getAttribute(GNE_ATTR_SHAPE_END);
690  // figure out the new name
691  int posBase = 0;
692  std::string baseName = edge->getMicrosimID();
693  if (edge->wasSplit()) {
694  const std::string::size_type sep_index = baseName.rfind('.');
695  if (sep_index != std::string::npos) { // edge may have been renamed in between
696  std::string posString = baseName.substr(sep_index + 1);
697  try {
698  posBase = GNEAttributeCarrier::parse<int>(posString.c_str());
699  baseName = baseName.substr(0, sep_index); // includes the .
700  } catch (NumberFormatException&) {
701  }
702  }
703  }
704  baseName += '.';
705  // create a new edge from the new junction to the previous destination
706  GNEEdge* secondPart = createEdge(newJunction, edge->getGNEJunctionDestiny(), edge,
707  undoList, baseName + toString(posBase + (int)linePos), true, false, false);
708  // fix connections from the split edge (must happen before changing SUMO_ATTR_TO)
709  edge->getGNEJunctionDestiny()->replaceIncomingConnections(edge, secondPart, undoList);
710  // modify the edge so that it ends at the new junction (and all incoming connections are preserved
711  undoList->p_add(new GNEChange_Attribute(edge, SUMO_ATTR_TO, newJunction->getID()));
712  // fix first part of geometry
713  newGeoms.first.pop_back();
714  newGeoms.first.erase(newGeoms.first.begin());
715  edge->setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
716  edge->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);
717  // fix second part of geometry
718  secondPart->setAttribute(GNE_ATTR_SHAPE_END, shapeEnd, undoList);
719  newGeoms.second.pop_back();
720  newGeoms.second.erase(newGeoms.second.begin());
721  secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
722  // reconnect across the split
723  for (int i = 0; i < (int)edge->getLanes().size(); ++i) {
724  undoList->add(new GNEChange_Connection(edge, NBEdge::Connection(i, secondPart->getNBEdge(), i), false, true), true);
725  }
726  // move connections at the destination junction from the original edge to the secondPart
727  for (GNECrossing* crossing : secondPart->getGNEJunctionDestiny()->getGNECrossings()) {
728  if (crossing->checkEdgeBelong(edge)) {
729  EdgeVector newNBEdges;
730  for (NBEdge* nbEdge : crossing->getNBCrossing()->edges) {
731  if (nbEdge == edge->getNBEdge()) {
732  newNBEdges.push_back(secondPart->getNBEdge());
733  } else {
734  newNBEdges.push_back(nbEdge);
735  }
736  }
737  crossing->setAttribute(SUMO_ATTR_EDGES, toString(newNBEdges), undoList);
738  }
739  }
740  undoList->p_end();
741  return newJunction;
742 }
743 
744 
745 void
746 GNENet::splitEdgesBidi(const std::set<GNEEdge*>& edges, const Position& pos, GNEUndoList* undoList) {
747  GNEJunction* newJunction = 0;
748  undoList->p_begin("split " + toString(SUMO_TAG_EDGE) + "s");
749  for (auto it : edges) {
750  newJunction = splitEdge(it, pos, undoList, newJunction);
751  }
752  undoList->p_end();
753 }
754 
755 
756 void
758  undoList->p_begin("reverse " + toString(SUMO_TAG_EDGE));
759  deleteEdge(edge, undoList, false); // still exists. we delete it so we can reuse the name in case of resplit
760  GNEEdge* reversed = createEdge(edge->getGNEJunctionDestiny(), edge->getGNEJunctionSource(), edge, undoList, edge->getID(), false, true);
761  assert(reversed != 0);
762  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
765  undoList->p_end();
766 }
767 
768 
769 GNEEdge*
771  undoList->p_begin("add reversed " + toString(SUMO_TAG_EDGE));
772  GNEEdge* reversed = nullptr;
774  // for rail edges, we assume bi-directional tracks are wanted
775  reversed = createEdge(edge->getGNEJunctionDestiny(), edge->getGNEJunctionSource(), edge, undoList, "-" + edge->getID(), false, true);
776  assert(reversed != 0);
777  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
780  } else {
781  // if the edge is centered it should probably connect somewhere else
782  // make it easy to move and reconnect it
783  PositionVector orig = edge->getNBEdge()->getGeometry();
784  PositionVector origInner = edge->getNBEdge()->getInnerGeometry();
785  const double tentativeShift = edge->getNBEdge()->getTotalWidth() + 2;
786  orig.move2side(-tentativeShift);
787  origInner.move2side(-tentativeShift);
788  GNEJunction* src = createJunction(orig.back(), undoList);
789  GNEJunction* dest = createJunction(orig.front(), undoList);
790  reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true);
791  assert(reversed != 0);
792  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
793  reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
794  // select the new edge and its nodes
795  reversed->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
796  src->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
797  dest->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
798  }
799  undoList->p_end();
800  return reversed;
801 }
802 
803 
804 void
806  undoList->p_begin("merge " + toString(SUMO_TAG_JUNCTION) + "s");
807  // place moved junction in the same position of target junction
809  // deleting edges changes in the underlying EdgeVector so we have to make a copy
810  const EdgeVector incoming = moved->getNBNode()->getIncomingEdges();
811  for (NBEdge* edge : incoming) {
812  // delete edges between the merged junctions
813  GNEEdge* e = myAttributeCarriers.edges[edge->getID()];
814  assert(e != 0);
815  if (e->getGNEJunctionSource() == target) {
816  deleteEdge(e, undoList, false);
817  } else {
818  undoList->p_add(new GNEChange_Attribute(e, SUMO_ATTR_TO, target->getID()));
819  }
820  }
821  // deleting edges changes in the underlying EdgeVector so we have to make a copy
822  const EdgeVector outgoing = moved->getNBNode()->getOutgoingEdges();
823  for (NBEdge* edge : outgoing) {
824  // delete edges between the merged junctions
825  GNEEdge* e = myAttributeCarriers.edges[edge->getID()];
826  assert(e != 0);
827  if (e->getGNEJunctionDestiny() == target) {
828  deleteEdge(e, undoList, false);
829  } else {
830  undoList->p_add(new GNEChange_Attribute(e, SUMO_ATTR_FROM, target->getID()));
831  }
832  }
833  // deleted moved junction
834  deleteJunction(moved, undoList);
835  undoList->p_end();
836 }
837 
838 
839 bool
841  // Check that there isn't another junction in the same position as Pos
842  for (auto i : myAttributeCarriers.junctions) {
843  if (i.second->getPositionInView() == pos) {
844  return false;
845  }
846  }
847  return true;
848 }
849 
850 
851 void
853  if (myNetSaved == true) {
854  WRITE_DEBUG("net has to be saved");
855  std::string additionalsSaved = (myAdditionalsSaved ? "saved" : "unsaved");
856  std::string shapeSaved = (myShapesSaved ? "saved" : "unsaved");
857  WRITE_DEBUG("Current saving Status: net unsaved, additionals " + additionalsSaved + ", shapes " + shapeSaved);
858  }
859  myNetSaved = !value;
860 }
861 
862 
863 bool
865  return myNetSaved;
866 }
867 
868 
869 void
871  // compute without volatile options and update network
872  computeAndUpdate(oc, false);
873  // write network
875  myNetSaved = true;
876 }
877 
878 
879 void
881  // compute without volatile options
882  computeAndUpdate(oc, false);
884 }
885 
886 
887 void
889  // compute without volatile options
890  computeAndUpdate(oc, false);
892 }
893 
894 
895 void
897  myViewNet = viewNet;
898 }
899 
900 
902 GNENet::retrieveJunction(const std::string& id, bool failHard) {
903  if (myAttributeCarriers.junctions.count(id)) {
904  return myAttributeCarriers.junctions[id];
905  } else if (failHard) {
906  // If junction wasn't found, throw exception
907  throw UnknownElement("Junction " + id);
908  } else {
909  return nullptr;
910  }
911 }
912 
913 
914 GNEEdge*
915 GNENet::retrieveEdge(const std::string& id, bool failHard) {
916  auto i = myAttributeCarriers.edges.find(id);
917  // If edge was found
918  if (i != myAttributeCarriers.edges.end()) {
919  return i->second;
920  } else if (failHard) {
921  // If edge wasn't found, throw exception
922  throw UnknownElement("Edge " + id);
923  } else {
924  return nullptr;
925  }
926 }
927 
928 
929 GNEEdge*
930 GNENet::retrieveEdge(GNEJunction* from, GNEJunction* to, bool failHard) {
931  assert((from != nullptr) && (to != nullptr));
932  // iterate over Junctions of net
933  for (auto i : myAttributeCarriers.edges) {
934  if ((i.second->getGNEJunctionSource() == from) && (i.second->getGNEJunctionDestiny() == to)) {
935  return i.second;
936  }
937  }
938  // if edge wasn' found, throw exception or return nullptr
939  if (failHard) {
940  throw UnknownElement("Edge with from='" + from->getID() + "' and to='" + to->getID() + "'");
941  } else {
942  return nullptr;
943  }
944 }
945 
946 
947 GNEPoly*
948 GNENet::retrievePolygon(const std::string& id, bool failHard) const {
949  if (myPolygons.get(id) != 0) {
950  return reinterpret_cast<GNEPoly*>(myPolygons.get(id));
951  } else if (failHard) {
952  // If Polygon wasn't found, throw exception
953  throw UnknownElement("Polygon " + id);
954  } else {
955  return nullptr;
956  }
957 }
958 
959 
960 GNEPOI*
961 GNENet::retrievePOI(const std::string& id, bool failHard) const {
962  if (myPOIs.get(id) != 0) {
963  return reinterpret_cast<GNEPOI*>(myPOIs.get(id));
964  } else if (failHard) {
965  // If POI wasn't found, throw exception
966  throw UnknownElement("POI " + id);
967  } else {
968  return nullptr;
969  }
970 }
971 
972 
974 GNENet::retrieveConnection(const std::string& id, bool failHard) const {
975  // iterate over junctions
976  for (auto i : myAttributeCarriers.junctions) {
977  // iterate over connections
978  for (auto j : i.second->getGNEConnections()) {
979  if (j->getID() == id) {
980  return j;
981  }
982  }
983  }
984  if (failHard) {
985  // If POI wasn't found, throw exception
986  throw UnknownElement("Connection " + id);
987  } else {
988  return nullptr;
989  }
990 }
991 
992 
993 std::vector<GNEConnection*>
994 GNENet::retrieveConnections(bool onlySelected) const {
995  std::vector<GNEConnection*> result;
996  // iterate over junctions
997  for (auto i : myAttributeCarriers.junctions) {
998  // iterate over connections
999  for (auto j : i.second->getGNEConnections()) {
1000  if (!onlySelected || j->isAttributeCarrierSelected()) {
1001  result.push_back(j);
1002  }
1003  }
1004  }
1005  return result;
1006 }
1007 
1008 
1009 GNECrossing*
1010 GNENet::retrieveCrossing(const std::string& id, bool failHard) const {
1011  // iterate over junctions
1012  for (auto i : myAttributeCarriers.junctions) {
1013  // iterate over crossings
1014  for (auto j : i.second->getGNECrossings()) {
1015  if (j->getID() == id) {
1016  return j;
1017  }
1018  }
1019  }
1020  if (failHard) {
1021  // If POI wasn't found, throw exception
1022  throw UnknownElement("Crossing " + id);
1023  } else {
1024  return nullptr;
1025  }
1026 }
1027 
1028 
1029 std::vector<GNECrossing*>
1030 GNENet::retrieveCrossings(bool onlySelected) const {
1031  std::vector<GNECrossing*> result;
1032  // iterate over junctions
1033  for (auto i : myAttributeCarriers.junctions) {
1034  // iterate over crossings
1035  for (auto j : i.second->getGNECrossings()) {
1036  if (!onlySelected || j->isAttributeCarrierSelected()) {
1037  result.push_back(j);
1038  }
1039  }
1040  }
1041  return result;
1042 }
1043 
1044 
1045 std::vector<GNEEdge*>
1046 GNENet::retrieveEdges(bool onlySelected) {
1047  std::vector<GNEEdge*> result;
1048  // returns edges depending of selection
1049  for (auto i : myAttributeCarriers.edges) {
1050  if (!onlySelected || i.second->isAttributeCarrierSelected()) {
1051  result.push_back(i.second);
1052  }
1053  }
1054  return result;
1055 }
1056 
1057 
1058 std::vector<GNELane*>
1059 GNENet::retrieveLanes(bool onlySelected) {
1060  std::vector<GNELane*> result;
1061  // returns lanes depending of selection
1062  for (auto i : myAttributeCarriers.edges) {
1063  for (auto j : i.second->getLanes()) {
1064  if (!onlySelected || j->isAttributeCarrierSelected()) {
1065  result.push_back(j);
1066  }
1067  }
1068  }
1069  return result;
1070 }
1071 
1072 
1073 GNELane*
1074 GNENet::retrieveLane(const std::string& id, bool failHard, bool checkVolatileChange) {
1075  const std::string edge_id = SUMOXMLDefinitions::getEdgeIDFromLane(id);
1076  GNEEdge* edge = retrieveEdge(edge_id, failHard);
1077  if (edge != 0) {
1078  GNELane* lane = nullptr;
1079  // search lane in lane's edges
1080  for (auto it : edge->getLanes()) {
1081  if (it->getID() == id) {
1082  lane = it;
1083  }
1084  }
1085  // throw exception or return nullptr if lane wasn't found
1086  if (lane == nullptr) {
1087  if (failHard) {
1088  // Throw exception if failHard is enabled
1089  throw UnknownElement(toString(SUMO_TAG_LANE) + " " + id);
1090  }
1091  } else {
1092  // check if the recomputing with volatile option has changed the number of lanes (needed for additionals)
1093  if (checkVolatileChange && (myEdgesAndNumberOfLanes.count(edge_id) == 1) && myEdgesAndNumberOfLanes[edge_id] != (int)edge->getLanes().size()) {
1094  return edge->getLanes().at(lane->getIndex() + 1);
1095  }
1096  return lane;
1097  }
1098  } else if (failHard) {
1099  // Throw exception if failHard is enabled
1100  throw UnknownElement(toString(SUMO_TAG_EDGE) + " " + edge_id);
1101  }
1102  return nullptr;
1103 }
1104 
1105 
1106 std::vector<GNEJunction*>
1107 GNENet::retrieveJunctions(bool onlySelected) {
1108  std::vector<GNEJunction*> result;
1109  // returns junctions depending of selection
1110  for (auto i : myAttributeCarriers.junctions) {
1111  if (!onlySelected || i.second->isAttributeCarrierSelected()) {
1112  result.push_back(i.second);
1113  }
1114  }
1115  return result;
1116 }
1117 
1118 
1119 std::vector<GNEShape*>
1120 GNENet::retrieveShapes(SumoXMLTag shapeTag, bool onlySelected) {
1121  std::vector<GNEShape*> result;
1122  // return dependingn of shape type
1123  if (shapeTag == SUMO_TAG_POLY) {
1124  // return all polys depending of onlySelected
1125  for (auto it : getPolygons()) {
1126  GNEShape* shape = dynamic_cast<GNEShape*>(it.second);
1127  if (!onlySelected || shape->isAttributeCarrierSelected()) {
1128  result.push_back(shape);
1129  }
1130  }
1131  } else {
1132  // check if we need to return a POI or POILane
1133  for (auto it : getPOIs()) {
1134  GNEPOI* poi = dynamic_cast<GNEPOI*>(it.second);
1135  if (poi && (poi->getTag() == shapeTag)) {
1136  // return all POIs or POILanes depending of onlySelected
1137  if (!onlySelected || poi->isAttributeCarrierSelected()) {
1138  result.push_back(poi);
1139  }
1140  }
1141  }
1142  }
1143  return result;
1144 }
1145 
1146 
1147 std::vector<GNEShape*>
1148 GNENet::retrieveShapes(bool onlySelected) {
1149  std::vector<GNEShape*> result;
1150  // return all polygons and POIs
1151  for (const auto& it : getPolygons()) {
1152  GNEPoly* poly = dynamic_cast<GNEPoly*>(it.second);
1153  if (!onlySelected || poly->isAttributeCarrierSelected()) {
1154  result.push_back(poly);
1155  }
1156  }
1157  for (const auto& it : getPOIs()) {
1158  GNEPOI* poi = dynamic_cast<GNEPOI*>(it.second);
1159  if (!onlySelected || poi->isAttributeCarrierSelected()) {
1160  result.push_back(poi);
1161  }
1162  }
1163  return result;
1164 }
1165 
1166 
1167 void
1170  update();
1171 }
1172 
1173 
1174 void
1177 }
1178 
1179 
1182  // obtain blocked GUIGlObject
1184  // Make sure that object exists
1185  if (object != nullptr) {
1186  // unblock and try to parse to AtributeCarrier
1188  GNEAttributeCarrier* ac = dynamic_cast<GNEAttributeCarrier*>(object);
1189  // If was sucesfully parsed, return it
1190  if (ac == nullptr) {
1191  throw ProcessError("GUIGlObject does not match the declared type");
1192  } else {
1193  return ac;
1194  }
1195  } else if (failHard) {
1196  throw ProcessError("Attempted to retrieve non-existant GUIGlObject");
1197  } else {
1198  return nullptr;
1199  }
1200 }
1201 
1202 
1203 std::vector<GNEAttributeCarrier*>
1205  std::vector<GNEAttributeCarrier*> result;
1206  if (type == SUMO_TAG_NOTHING) {
1207  // return all elements
1208  for (auto i : myAttributeCarriers.junctions) {
1209  result.push_back(i.second);
1210  for (auto j : i.second->getGNECrossings()) {
1211  result.push_back(j);
1212  }
1213  }
1214  for (auto i : myAttributeCarriers.edges) {
1215  result.push_back(i.second);
1216  for (auto j : i.second->getLanes()) {
1217  result.push_back(j);
1218  }
1219  for (auto j : i.second->getGNEConnections()) {
1220  result.push_back(j);
1221  }
1222  }
1223  for (auto i : myAttributeCarriers.additionals) {
1224  for (auto j : i.second) {
1225  result.push_back(j.second);
1226  }
1227  }
1228  for (auto i : myPolygons) {
1229  result.push_back(dynamic_cast<GNEPoly*>(i.second));
1230  }
1231  for (auto i : myPOIs) {
1232  result.push_back(dynamic_cast<GNEPOI*>(i.second));
1233  }
1234  } else if (GNEAttributeCarrier::getTagProperties(type).isAdditional()) {
1235  // only returns additionals of a certain type.
1236  for (auto i : myAttributeCarriers.additionals.at(type)) {
1237  result.push_back(i.second);
1238  }
1239  } else {
1240  // return only a part of elements, depending of type
1241  switch (type) {
1242  case SUMO_TAG_JUNCTION:
1243  for (auto i : myAttributeCarriers.junctions) {
1244  result.push_back(i.second);
1245  }
1246  break;
1247  case SUMO_TAG_EDGE:
1248  for (auto i : myAttributeCarriers.edges) {
1249  result.push_back(i.second);
1250  }
1251  break;
1252  case SUMO_TAG_LANE:
1253  for (auto i : myAttributeCarriers.edges) {
1254  for (auto j : i.second->getLanes()) {
1255  result.push_back(j);
1256  }
1257  }
1258  break;
1259  case SUMO_TAG_CONNECTION:
1260  for (auto i : myAttributeCarriers.edges) {
1261  for (auto j : i.second->getGNEConnections()) {
1262  result.push_back(j);
1263  }
1264  }
1265  break;
1266  case SUMO_TAG_CROSSING:
1267  for (auto i : myAttributeCarriers.junctions) {
1268  for (auto j : i.second->getGNECrossings()) {
1269  result.push_back(j);
1270  }
1271  }
1272  break;
1273  case SUMO_TAG_POLY:
1274  for (auto i : myPolygons) {
1275  result.push_back(dynamic_cast<GNEPoly*>(i.second));
1276  }
1277  break;
1278  case SUMO_TAG_POI:
1279  case SUMO_TAG_POILANE:
1280  for (auto i : myPOIs) {
1281  result.push_back(dynamic_cast<GNEPOI*>(i.second));
1282  }
1283  break;
1284  default:
1285  // return nothing
1286  break;
1287  }
1288  }
1289  return result;
1290 }
1291 
1292 
1293 void
1294 GNENet::computeEverything(GNEApplicationWindow* window, bool force, bool volatileOptions, std::string additionalPath, std::string shapePath) {
1295  if (!myNeedRecompute) {
1296  if (force) {
1297  if (volatileOptions) {
1298  window->setStatusBarText("Forced computing junctions with volatile options ...");
1299  } else {
1300  window->setStatusBarText("Forced computing junctions ...");
1301  }
1302  } else {
1303  return;
1304  }
1305  } else {
1306  if (volatileOptions) {
1307  window->setStatusBarText("Computing junctions with volatile options ...");
1308  } else {
1309  window->setStatusBarText("Computing junctions ...");
1310  }
1311  }
1312  // save current number of lanes for every edge if recomputing is with volatile options
1313  if (volatileOptions) {
1314  for (auto it : myAttributeCarriers.edges) {
1315  myEdgesAndNumberOfLanes[it.second->getID()] = (int)it.second->getLanes().size();
1316  }
1317  }
1318 
1319  // compute and update
1321  computeAndUpdate(oc, volatileOptions);
1322 
1323  // load additionals if was recomputed with volatile options
1324  if (additionalPath != "") {
1325  // fill additionals with tags
1326  auto listOfTags = GNEAttributeCarrier::allowedAdditionalTags(false);
1327  for (auto i : listOfTags) {
1328  myAttributeCarriers.additionals.insert(std::make_pair(i, std::map<std::string, GNEAdditional*>()));
1329  }
1330 
1331  // default vehicle type is always available
1333  myAttributeCarriers.additionals.at(defaultVehicleType->getTag()).insert(std::make_pair(defaultVehicleType->getID(), defaultVehicleType));
1334  defaultVehicleType->incRef("GNENet::DEFAULT_VEHTYPE");
1335 
1336  // Create additional handler
1337  GNEAdditionalHandler additionalHandler(additionalPath, myViewNet, false);
1338  // Run parser
1339  if (!XMLSubSys::runParser(additionalHandler, additionalPath, false)) {
1340  WRITE_MESSAGE("Loading of " + additionalPath + " failed.");
1341  } else {
1342  // update view
1343  update();
1344  }
1345  // clear myEdgesAndNumberOfLanes after reload additionals
1346  myEdgesAndNumberOfLanes.clear();
1347  }
1348  // load shapes if was recomputed with volatile options
1349  if (shapePath != "") {
1350  // new shapes has to be inserted without possibility of undo/redo
1351  myAllowUndoShapes = false;
1352  GNEApplicationWindow::GNEShapeHandler handler(shapePath, this);
1353  if (!XMLSubSys::runParser(handler, shapePath, false)) {
1354  WRITE_MESSAGE("Loading of " + shapePath + " failed.");
1355  }
1356  // restore flag
1357  myAllowUndoShapes = true;
1358  }
1359  window->getApp()->endWaitCursor();
1360  window->setStatusBarText("Finished computing junctions.");
1361  update();
1362 }
1363 
1364 
1365 void
1367  // recompute tl-logics
1370  // iterate over traffic lights definitions. Make a copy because invalid
1371  // definitions will be removed (and would otherwise destroy the iterator)
1372  const std::set<NBTrafficLightDefinition*> tlsDefs = junction->getNBNode()->getControllingTLS();
1373  for (auto it : tlsDefs) {
1374  it->setParticipantsInformation();
1375  it->setTLControllingInformation();
1376  tllCont.computeSingleLogic(oc, it);
1377  }
1378 
1379  // @todo compute connections etc...
1380 }
1381 
1382 
1383 void
1385  myNeedRecompute = true;
1386 }
1387 
1388 
1389 bool
1391  for (auto n : myAttributeCarriers.junctions) {
1392  if (n.second->getGNECrossings().size() > 0) {
1393  return true;
1394  }
1395  }
1396  return false;
1397 }
1398 
1399 
1400 FXApp*
1402  return myViewNet->getApp();
1403 }
1404 
1405 
1406 NBNetBuilder*
1408  return myNetBuilder;
1409 }
1410 
1411 
1412 bool
1414  std::vector<GNEJunction*> selectedJunctions = retrieveJunctions(true);
1415  if (selectedJunctions.size() < 2) {
1416  return false;
1417  }
1418  EdgeVector allIncoming;
1419  EdgeVector allOutgoing;
1420  std::set<NBNode*, ComparatorIdLess> cluster;
1421  for (auto it : selectedJunctions) {
1422  cluster.insert(it->getNBNode());
1423  const EdgeVector& incoming = it->getNBNode()->getIncomingEdges();
1424  allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end());
1425  const EdgeVector& outgoing = it->getNBNode()->getOutgoingEdges();
1426  allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end());
1427  }
1428  // create new junction
1429  Position pos;
1430  Position oldPos;
1431  bool setTL;
1432  std::string id = "cluster";
1433  TrafficLightType type;
1434  SumoXMLNodeType nodeType = NODETYPE_UNKNOWN;
1435  myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type, nodeType);
1436  // save position
1437  oldPos = pos;
1438 
1439  // Check that there isn't another junction in the same position as Pos but doesn't belong to cluster
1440  for (auto i : myAttributeCarriers.junctions) {
1441  if ((i.second->getPositionInView() == pos) && (cluster.find(i.second->getNBNode()) == cluster.end())) {
1442  // show warning in gui testing debug mode
1443  WRITE_DEBUG("Opening FXMessageBox 'Join non-selected junction'");
1444  // Ask confirmation to user
1445  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1446  ("Position of joined " + toString(SUMO_TAG_JUNCTION)).c_str(), "%s",
1447  ("There is another unselected " + toString(SUMO_TAG_JUNCTION) + " in the same position of joined " + toString(SUMO_TAG_JUNCTION) +
1448  + ".\nIt will be joined with the other selected " + toString(SUMO_TAG_JUNCTION) + "s. Continue?").c_str());
1449  if (answer != 1) { // 1:yes, 2:no, 4:esc
1450  // write warning if netedit is running in testing mode
1451  if (answer == 2) {
1452  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'No'");
1453  } else if (answer == 4) {
1454  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'ESC'");
1455  }
1456  return false;
1457  } else {
1458  // write warning if netedit is running in testing mode
1459  WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'Yes'");
1460  // select conflicted junction an join all again
1461  i.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1462  return joinSelectedJunctions(undoList);
1463  }
1464  }
1465  }
1466 
1467  // use checkJunctionPosition to avoid conflicts with junction in the same position as others
1468  while (checkJunctionPosition(pos) == false) {
1469  pos.setx(pos.x() + 0.1);
1470  pos.sety(pos.y() + 0.1);
1471  }
1472 
1473  // start with the join selected junctions
1474  undoList->p_begin("Join selected " + toString(SUMO_TAG_JUNCTION) + "s");
1475  GNEJunction* joined = createJunction(pos, undoList);
1476  joined->setAttribute(SUMO_ATTR_TYPE, toString(nodeType), undoList); // i.e. rail crossing
1477  if (setTL) {
1479  // XXX ticket831
1480  //joined-><getTrafficLight>->setAttribute(SUMO_ATTR_TYPE, toString(type), undoList);
1481  }
1482 
1483  // #3128 this is not undone when calling 'undo'
1485 
1486  // first remove all crossing of the involved junctions and edges
1487  // (otherwise edge removal will trigger discarding)
1488  std::vector<NBNode::Crossing> oldCrossings;
1489  for (auto i : selectedJunctions) {
1490  while (i->getGNECrossings().size() > 0) {
1491  GNECrossing* crossing = i->getGNECrossings().front();
1492  oldCrossings.push_back(*crossing->getNBCrossing());
1493  deleteCrossing(crossing, undoList);
1494  }
1495  }
1496 
1497  // preserve old connections
1498  for (auto it : selectedJunctions) {
1499  it->setLogicValid(false, undoList);
1500  }
1501  // remap edges
1502  for (auto it : allIncoming) {
1503  undoList->p_add(new GNEChange_Attribute(myAttributeCarriers.edges[it->getID()], SUMO_ATTR_TO, joined->getID()));
1504  }
1505 
1506  EdgeSet edgesWithin;
1507  for (auto it : allOutgoing) {
1508  // delete edges within the cluster
1509  GNEEdge* e = myAttributeCarriers.edges[it->getID()];
1510  assert(e != 0);
1511  if (e->getGNEJunctionDestiny() == joined) {
1512  edgesWithin.insert(it);
1513  deleteEdge(e, undoList, false);
1514  } else {
1515  undoList->p_add(new GNEChange_Attribute(myAttributeCarriers.edges[it->getID()], SUMO_ATTR_FROM, joined->getID()));
1516  }
1517  }
1518 
1519  // remap all crossing of the involved junctions and edges
1520  for (auto nbc : oldCrossings) {
1521  bool keep = true;
1522  for (NBEdge* e : nbc.edges) {
1523  if (edgesWithin.count(e) != 0) {
1524  keep = false;
1525  break;
1526  }
1527  };
1528  if (keep) {
1529  undoList->add(new GNEChange_Crossing(joined, nbc.edges, nbc.width,
1530  nbc.priority || joined->getNBNode()->isTLControlled(),
1531  nbc.customTLIndex, nbc.customTLIndex2, nbc.customShape,
1532  false, true), true);
1533  }
1534  }
1535 
1536  // delete original junctions
1537  for (auto it : selectedJunctions) {
1538  deleteJunction(it, undoList);
1539  }
1540  joined->setAttribute(SUMO_ATTR_ID, id, undoList);
1541 
1542 
1543  // check if joined junction had to change their original position to avoid errors
1544  if (pos != oldPos) {
1545  joined->setAttribute(SUMO_ATTR_POSITION, toString(oldPos), undoList);
1546  }
1547  undoList->p_end();
1548  return true;
1549 }
1550 
1551 
1552 bool
1554  // obtain current net's crossings
1555  std::vector<GNECrossing*> myNetCrossings;
1556  for (auto it : myAttributeCarriers.junctions) {
1557  myNetCrossings.reserve(myNetCrossings.size() + it.second->getGNECrossings().size());
1558  myNetCrossings.insert(myNetCrossings.end(), it.second->getGNECrossings().begin(), it.second->getGNECrossings().end());
1559  }
1560  // obtain invalid crossigns
1561  std::vector<GNECrossing*> myInvalidCrossings;
1562  for (auto i = myNetCrossings.begin(); i != myNetCrossings.end(); i++) {
1563  if ((*i)->getNBCrossing()->valid == false) {
1564  myInvalidCrossings.push_back(*i);
1565  }
1566  }
1567 
1568  if (myInvalidCrossings.empty()) {
1569  // show warning in gui testing debug mode
1570  WRITE_DEBUG("Opening FXMessageBox 'No crossing to remove'");
1571  // open a dialog informing that there isn't crossing to remove
1572  FXMessageBox::warning(getApp(), MBOX_OK,
1573  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1574  ("There is no invalid " + toString(SUMO_TAG_CROSSING) + "s to remove").c_str());
1575  // show warning in gui testing debug mode
1576  WRITE_DEBUG("Closed FXMessageBox 'No crossing to remove' with 'OK'");
1577  } else {
1578  std::string plural = myInvalidCrossings.size() == 1 ? ("") : ("s");
1579  // show warning in gui testing debug mode
1580  WRITE_DEBUG("Opening FXMessageBox 'clear crossings'");
1581  // Ask confirmation to user
1582  FXuint answer = FXMessageBox::question(getApp(), MBOX_YES_NO,
1583  ("Clear " + toString(SUMO_TAG_CROSSING) + "s").c_str(), "%s",
1584  ("Clear " + toString(SUMO_TAG_CROSSING) + plural + " will be removed. Continue?").c_str());
1585  if (answer != 1) { // 1:yes, 2:no, 4:esc
1586  // write warning if netedit is running in testing mode
1587  if (answer == 2) {
1588  WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'No'");
1589  } else if (answer == 4) {
1590  WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'ESC'");
1591  }
1592  } else {
1593  undoList->p_begin("Clean " + toString(SUMO_TAG_CROSSING) + "s");
1594  for (auto i = myInvalidCrossings.begin(); i != myInvalidCrossings.end(); i++) {
1595  deleteCrossing((*i), undoList);
1596  }
1597  undoList->p_end();
1598  }
1599  }
1600  return 1;
1601 }
1602 
1603 
1604 void
1606  undoList->p_begin("Clean " + toString(SUMO_TAG_JUNCTION) + "s");
1607  std::vector<GNEJunction*> toRemove;
1608  for (auto it : myAttributeCarriers.junctions) {
1609  GNEJunction* junction = it.second;
1610  if (junction->getNBNode()->getEdges().size() == 0) {
1611  toRemove.push_back(junction);
1612  }
1613  }
1614  for (auto it : toRemove) {
1615  deleteJunction(it, undoList);
1616  }
1617  undoList->p_end();
1618 }
1619 
1620 
1621 void
1623  assert(junction->getNBNode()->checkIsRemovable());
1624  // start operation
1625  undoList->p_begin("Replace junction by geometry");
1626  // obtain Edges to join
1627  std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
1628  // clear connections of junction to replace
1629  clearJunctionConnections(junction, undoList);
1630  // iterate over NBEdges to join
1631  for (auto j : toJoin) {
1632  // obtain GNEEdges
1633  GNEEdge* begin = myAttributeCarriers.edges[j.first->getID()];
1634  GNEEdge* continuation = myAttributeCarriers.edges[j.second->getID()];
1635  // remove connections between the edges
1636  std::vector<NBEdge::Connection> connections = begin->getNBEdge()->getConnections();
1637  for (auto con : connections) {
1638  undoList->add(new GNEChange_Connection(begin, con, false, false), true);
1639  }
1640  // fix shape of replaced edge
1641  PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
1642  if (begin->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1643  newShape.push_back(junction->getNBNode()->getPosition());
1644  } else {
1645  newShape.push_back(begin->getNBEdge()->getGeometry()[-1]);
1646  }
1647  if (continuation->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1648  newShape.push_back_noDoublePos(junction->getNBNode()->getPosition());
1649  } else {
1650  newShape.push_back_noDoublePos(continuation->getNBEdge()->getGeometry()[0]);
1651  }
1652  // replace incoming edge
1653  replaceIncomingEdge(continuation, begin, undoList);
1654 
1655  newShape.append(continuation->getNBEdge()->getInnerGeometry());
1656  begin->setAttribute(GNE_ATTR_SHAPE_END, continuation->getAttribute(GNE_ATTR_SHAPE_END), undoList);
1657  begin->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
1658  }
1659  //delete replaced junction
1660  deleteJunction(junction, undoList);
1661  // finish operation
1662  undoList->p_end();
1663 }
1664 
1665 
1666 void
1668  std::vector<Position> endpoints = junction->getNBNode()->getEndPoints();
1669  if (endpoints.size() < 2) {
1670  return;
1671  }
1672  // start operation
1673  undoList->p_begin("Split junction");
1674  //std::cout << "split junction at endpoints: " << toString(endpoints) << "\n";
1675  junction->setLogicValid(false, undoList);
1676  for (Position pos : endpoints) {
1677  GNEJunction* newJunction = createJunction(pos, undoList);
1678  for (GNEEdge* e : junction->getGNEIncomingEdges()) {
1679  if (e->getNBEdge()->getGeometry().back().almostSame(pos)) {
1680  //std::cout << " " << e->getID() << " pos=" << pos << "\n";
1681  undoList->p_add(new GNEChange_Attribute(e, SUMO_ATTR_TO, newJunction->getID()));
1682  }
1683  }
1684  for (GNEEdge* e : junction->getGNEOutgoingEdges()) {
1685  if (e->getNBEdge()->getGeometry().front().almostSame(pos)) {
1686  //std::cout << " " << e->getID() << " pos=" << pos << "\n";
1687  undoList->p_add(new GNEChange_Attribute(e, SUMO_ATTR_FROM, newJunction->getID()));
1688  }
1689  }
1690  }
1691  deleteJunction(junction, undoList);
1692  // finish operation
1693  undoList->p_end();
1694 }
1695 
1696 
1697 
1698 void
1700  undoList->p_begin("clear junction connections");
1701  std::vector<GNEConnection*> connections = junction->getGNEConnections();
1702  // Iterate over all connections and clear it
1703  for (auto i : connections) {
1704  deleteConnection(i, undoList);
1705  }
1706  undoList->p_end();
1707 }
1708 
1709 
1710 void
1712  undoList->p_begin("reset junction connections");
1713  // first clear connections
1714  clearJunctionConnections(junction, undoList);
1715  // invalidate logic to create new connections in the next recomputing
1716  junction->setLogicValid(false, undoList);
1717  undoList->p_end();
1718 }
1719 
1720 
1721 void
1722 GNENet::renameEdge(GNEEdge* edge, const std::string& newID) {
1723  myAttributeCarriers.edges.erase(edge->getNBEdge()->getID());
1724  myNetBuilder->getEdgeCont().rename(edge->getNBEdge(), newID);
1725  edge->setMicrosimID(newID);
1726  myAttributeCarriers.edges[newID] = edge;
1727  // rename all connections related to this edge
1728  for (auto i : edge->getLanes()) {
1729  i->updateConnectionIDs();
1730  }
1731 }
1732 
1733 
1734 void
1735 GNENet::changeEdgeEndpoints(GNEEdge* edge, const std::string& newSource, const std::string& newDest) {
1736  NBNode* from = retrieveJunction(newSource)->getNBNode();
1737  NBNode* to = retrieveJunction(newDest)->getNBNode();
1738  edge->getNBEdge()->reinitNodes(from, to);
1739  requireRecompute();
1740  update();
1741 }
1742 
1743 
1744 GNEViewNet*
1746  return myViewNet;
1747 }
1748 
1749 
1750 std::vector<GNEAttributeCarrier*>
1752  std::vector<GNEAttributeCarrier*> result;
1753  result.reserve(gSelected.getSelected().size());
1754  for (auto i : gSelected.getSelected()) {
1756  if (AC && AC->isAttributeCarrierSelected()) {
1757  result.push_back(AC);
1758  }
1759  }
1760  return result;
1761 }
1762 
1763 
1766  return myNetBuilder->getTLLogicCont();
1767 }
1768 
1769 
1770 void
1771 GNENet::renameJunction(GNEJunction* junction, const std::string& newID) {
1772  std::string oldID = junction->getID();
1773  myAttributeCarriers.junctions.erase(junction->getNBNode()->getID());
1774  myNetBuilder->getNodeCont().rename(junction->getNBNode(), newID);
1775  junction->setMicrosimID(newID);
1776  myAttributeCarriers.junctions[newID] = junction;
1777  // build crossings
1778  junction->getNBNode()->buildCrossings();
1779 }
1780 
1781 
1782 void
1784  myExplicitTurnarounds.insert(id);
1785 }
1786 
1787 
1788 void
1790  myExplicitTurnarounds.erase(id);
1791 }
1792 
1793 
1795 GNENet::retrieveAdditional(SumoXMLTag type, const std::string& id, bool hardFail) const {
1796  if ((myAttributeCarriers.additionals.count(type) > 0) && (myAttributeCarriers.additionals.at(type).count(id) != 0)) {
1797  return myAttributeCarriers.additionals.at(type).at(id);
1798  } else if (hardFail) {
1799  throw ProcessError("Attempted to retrieve non-existant additional");
1800  } else {
1801  return nullptr;
1802  }
1803 }
1804 
1805 
1806 std::vector<GNEAdditional*>
1807 GNENet::retrieveAdditionals(bool onlySelected) const {
1808  std::vector<GNEAdditional*> result;
1809  // returns additionals depending of selection
1810  for (auto i : myAttributeCarriers.additionals) {
1811  for (auto j : i.second) {
1812  if (!onlySelected || j.second->isAttributeCarrierSelected()) {
1813  result.push_back(j.second);
1814  }
1815  }
1816  }
1817  return result;
1818 }
1819 
1820 
1821 const std::map<std::string, GNEAdditional*>&
1823  return myAttributeCarriers.additionals.at(type);
1824 }
1825 
1826 
1827 int
1829  int counter = 0;
1830  for (auto i : myAttributeCarriers.additionals) {
1831  if ((type == SUMO_TAG_NOTHING) || (type == i.first)) {
1832  counter += (int)i.second.size();
1833  }
1834  }
1835  return counter;
1836 }
1837 
1838 
1839 void
1840 GNENet::updateAdditionalID(const std::string& oldID, GNEAdditional* additional) {
1841  if (myAttributeCarriers.additionals.at(additional->getTag()).count(oldID) == 0) {
1842  throw ProcessError(toString(additional->getTag()) + " with old ID='" + oldID + "' doesn't exist");
1843  } else {
1844  // remove an insert additional again into container
1845  myAttributeCarriers.additionals.at(additional->getTag()).erase(oldID);
1846  myAttributeCarriers.additionals.at(additional->getTag()).insert(std::make_pair(additional->getID(), additional));
1847  // additionals has to be saved
1849  }
1850 }
1851 
1852 
1853 void
1855  if (myAdditionalsSaved == true) {
1856  WRITE_DEBUG("Additionals has to be saved");
1857  std::string netSaved = (myNetSaved ? "saved" : "unsaved");
1858  std::string shapeSaved = (myShapesSaved ? "saved" : "unsaved");
1859  WRITE_DEBUG("Current saving Status: net " + netSaved + ", additionals unsaved, shapes " + shapeSaved);
1860  }
1861  myAdditionalsSaved = !value;
1862  if (myViewNet != nullptr) {
1863  if (myAdditionalsSaved) {
1865  } else {
1867  }
1868  }
1869 }
1870 
1871 
1872 void
1873 GNENet::saveAdditionals(const std::string& filename) {
1874  // obtain invalid stopping places and detectors
1875  std::vector<GNEStoppingPlace*> invalidStoppingPlaces;
1876  std::vector<GNEDetector*> invalidDetectors;
1877  for (auto i : myAttributeCarriers.additionals) {
1878  for (auto j : i.second) {
1879  GNEStoppingPlace* stoppingPlace = dynamic_cast<GNEStoppingPlace*>(j.second);
1880  GNEDetector* detector = dynamic_cast<GNEDetector*>(j.second);
1881  // check if has to be fixed
1882  if ((stoppingPlace != nullptr) && (stoppingPlace->areStoppingPlacesPositionsFixed() == false)) {
1883  invalidStoppingPlaces.push_back(stoppingPlace);
1884  } else if ((detector != nullptr) && (detector->isDetectorPositionFixed() == false)) {
1885  invalidDetectors.push_back(detector);
1886  }
1887  }
1888  }
1889  // if there are invalid StoppingPlaces or detectors, open GNEDialog_FixAdditionalPositions
1890  if (invalidStoppingPlaces.size() > 0 || invalidDetectors.size() > 0) {
1891  // 0 -> Canceled Saving, with or whithout selecting invalid stopping places and E2
1892  // 1 -> Invalid stoppingPlaces and E2 fixed, friendlyPos enabled, or saved with invalid positions
1893  GNEDialog_FixAdditionalPositions fixAdditionalPositionsDialog(myViewNet, invalidStoppingPlaces, invalidDetectors);
1894  if (fixAdditionalPositionsDialog.execute() == 0) {
1895  // Here a console message
1896  ;
1897  } else {
1898  saveAdditionalsConfirmed(filename);
1899  }
1900  // set focus again in viewNet
1901  myViewNet->setFocus();
1902  } else {
1903  saveAdditionalsConfirmed(filename);
1904  }
1905  // change value of flag
1906  myAdditionalsSaved = true;
1907  // show debug information
1908  WRITE_DEBUG("Additionals saved");
1909 }
1910 
1911 
1912 std::string
1914  int counter = 0;
1915  while (myAttributeCarriers.additionals.at(type).count(toString(type) + "_" + toString(counter)) != 0) {
1916  counter++;
1917  }
1918  return (toString(type) + "_" + toString(counter));
1919 }
1920 
1921 
1922 void
1923 GNENet::saveAdditionalsConfirmed(const std::string& filename) {
1924  OutputDevice& device = OutputDevice::getDevice(filename);
1925  device.writeXMLHeader("additional", "additional_file.xsd");
1926  // first write all vehicle types (Except DEFAULT_VTYPE_ID)
1927  for (auto i : myAttributeCarriers.additionals) {
1928  if (i.first == SUMO_TAG_VTYPE) {
1929  for (auto j : i.second) {
1930  if (j.second->getID() != DEFAULT_VTYPE_ID) {
1931  j.second->writeAdditional(device);
1932  }
1933  }
1934  }
1935  }
1936  // now write all routes
1937  for (auto i : myAttributeCarriers.additionals) {
1938  if (i.first == SUMO_TAG_ROUTE) {
1939  for (auto j : i.second) {
1940  j.second->writeAdditional(device);
1941  }
1942  }
1943  }
1944  // now write all route probes (see Ticket #4058)
1945  for (auto i : myAttributeCarriers.additionals) {
1946  if (i.first == SUMO_TAG_ROUTEPROBE) {
1947  for (auto j : i.second) {
1948  j.second->writeAdditional(device);
1949  }
1950  }
1951  }
1952  // now write all stoppingPlaces
1953  for (auto i : myAttributeCarriers.additionals) {
1955  for (auto j : i.second) {
1956  // only save stoppingPlaces that doesn't have Additional parents, because they are automatically writed by writeAdditional(...) parent's function
1957  if (j.second->getFirstAdditionalParent() == nullptr) {
1958  j.second->writeAdditional(device);
1959  }
1960  }
1961  }
1962  }
1963  // now write all detectors
1964  for (auto i : myAttributeCarriers.additionals) {
1966  for (auto j : i.second) {
1967  // only save Detectors that doesn't have Additional parents, because they are automatically writed by writeAdditional(...) parent's function
1968  if (j.second->getFirstAdditionalParent() == nullptr) {
1969  j.second->writeAdditional(device);
1970  }
1971  }
1972  }
1973  }
1974  // finally write rest of additionals
1975  for (auto i : myAttributeCarriers.additionals) {
1976  const auto& tagValue = GNEAttributeCarrier::getTagProperties(i.first);
1977  if (!tagValue.isStoppingPlace() && !tagValue.isDetector() && (i.first != SUMO_TAG_ROUTEPROBE) && (i.first != SUMO_TAG_VTYPE) && (i.first != SUMO_TAG_ROUTE)) {
1978  for (auto j : i.second) {
1979  // only save additionals that doesn't have Additional parents, because they are automatically writed by writeAdditional(...) parent's function
1980  if (j.second->getFirstAdditionalParent() == nullptr) {
1981  j.second->writeAdditional(device);
1982  }
1983  }
1984  }
1985  }
1986  device.close();
1987 }
1988 
1989 
1990 GNEPoly*
1991 GNENet::addPolygonForEditShapes(GNENetElement* netElement, const PositionVector& shape, bool fill, RGBColor col) {
1992  if (shape.size() > 0) {
1993  // create poly for edit shapes
1994  GNEPoly* shapePoly = new GNEPoly(this, "edit_shape", "edit_shape", shape, false, true, col, GLO_POLYGON, 0, "", false, false , false);
1995  shapePoly->setShapeEditedElement(netElement);
1996  shapePoly->setFill(fill);
1997  shapePoly->setLineWidth(0.3);
1998  myGrid.addAdditionalGLObject(shapePoly);
1999  myViewNet->update();
2000  return shapePoly;
2001  } else {
2002  throw ProcessError("shape cannot be empty");
2003  }
2004 }
2005 
2006 
2007 void
2009  if (polygon) {
2010  // remove it from Inspector Frame
2012  // Remove from grid
2014  myViewNet->update();
2015  } else {
2016  throw ProcessError("Polygon for edit shapes has to be inicializated");
2017  }
2018 }
2019 
2020 
2021 std::string
2023  // generate tag depending of type of shape
2024  if (shapeTag == SUMO_TAG_POLY) {
2025  int counter = 0;
2026  std::string newID = "poly_" + toString(counter);
2027  // generate new IDs to find a non-assigned ID
2028  while (myPolygons.get(newID) != nullptr) {
2029  counter++;
2030  newID = "poly_" + toString(counter);
2031  }
2032  return newID;
2033  } else {
2034  int counter = 0;
2035  std::string newID = "POI_" + toString(counter);
2036  // generate new IDs to find a non-assigned ID
2037  while (myPOIs.get(newID) != nullptr) {
2038  counter++;
2039  newID = "POI_" + toString(counter);
2040  }
2041  return newID;
2042  }
2043 }
2044 
2045 
2046 void
2047 GNENet::changeShapeID(GNEShape* s, const std::string& OldID) {
2048  if (s->getTag() == SUMO_TAG_POLY) {
2049  if (myPolygons.get(OldID) == 0) {
2050  throw UnknownElement("Polygon " + OldID);
2051  } else {
2052  myPolygons.changeID(OldID, s->getID());
2053  }
2054  } else {
2055  if (myPOIs.get(OldID) == 0) {
2056  throw UnknownElement("POI " + OldID);
2057  } else {
2058  myPOIs.changeID(OldID, s->getID());
2059  }
2060  }
2061 }
2062 
2063 
2064 void
2066  if (myShapesSaved == true) {
2067  WRITE_DEBUG("Shapes has to be saved");
2068  std::string netSaved = (myNetSaved ? "saved" : "unsaved");
2069  std::string additionalsSaved = (myAdditionalsSaved ? "saved" : "unsaved");
2070  WRITE_DEBUG("Current saving Status: net " + netSaved + ", additionals " + additionalsSaved + ", shapes unsaved");
2071  }
2072  myShapesSaved = !value;
2073  if (myShapesSaved) {
2075  } else {
2077  }
2078 }
2079 
2080 
2081 void
2082 GNENet::saveShapes(const std::string& filename) {
2083  // save Shapes
2084  OutputDevice& device = OutputDevice::getDevice(filename);
2085  device.writeXMLHeader("additional", "additional_file.xsd");
2086  // write only visible polygons
2087  for (const auto& i : myPolygons) {
2088  dynamic_cast<GNEShape*>(i.second)->writeShape(device);
2089  }
2090  // write only visible POIs
2091  for (const auto& i : myPOIs) {
2092  dynamic_cast<GNEShape*>(i.second)->writeShape(device);
2093  }
2094  device.close();
2095  // change flag to true
2096  myShapesSaved = true;
2097  // show debug information
2098  WRITE_DEBUG("Shapes saved");
2099 }
2100 
2101 
2102 int
2104  return (int)(myPolygons.size() + myPOIs.size());
2105 }
2106 
2107 
2108 void
2110  if (myTLSProgramsSaved == true) {
2111  WRITE_DEBUG("TLSPrograms has to be saved");
2112  }
2113  myTLSProgramsSaved = false;
2115 }
2116 
2117 
2118 void
2119 GNENet::saveTLSPrograms(const std::string& filename) {
2120  // open output device
2121  OutputDevice& device = OutputDevice::getDevice(filename);
2122  device.openTag("additionals");
2123  // write traffic lights using NWWriter
2125  device.close();
2126  // change flag to true
2127  myTLSProgramsSaved = true;
2128  // show debug information
2129  WRITE_DEBUG("TLSPrograms saved");
2130 }
2131 
2132 
2133 int
2135  return -1;
2136 }
2137 
2138 
2139 void
2141  // Check if additional element exists before insertion
2142  if (myAttributeCarriers.additionals.at(additional->getTag()).count(additional->getID()) == 0) {
2143  myAttributeCarriers.additionals.at(additional->getTag()).insert(std::make_pair(additional->getID(), additional));
2144  // only add drawable elements in grid
2145  if (additional->getTagProperties(additional->getTag()).isDrawable()) {
2146  myGrid.addAdditionalGLObject(additional);
2147  }
2148  // check if additional is selected
2149  if (additional->isAttributeCarrierSelected()) {
2150  additional->selectAttributeCarrier(false);
2151  }
2152  // update geometry after insertion of additionals
2153  additional->updateGeometry(true);
2154  // additionals has to be saved
2156  } else {
2157  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' already exist");
2158  }
2159 }
2160 
2161 
2162 void
2164  // Check if additional element exists before deletion
2165  if (myAttributeCarriers.additionals.at(additional->getTag()).count(additional->getID()) == 0) {
2166  throw ProcessError(toString(additional->getTag()) + " with ID='" + additional->getID() + "' doesn't exist");
2167  } else {
2168  // remove it from Inspector Frame
2170  // Remove from container
2171  myAttributeCarriers.additionals.at(additional->getTag()).erase(additional->getID());
2172  // only remove drawable elements of grid
2173  if (additional->getTagProperties(additional->getTag()).isDrawable()) {
2174  myGrid.removeAdditionalGLObject(additional);
2175  }
2176  // check if additional is selected
2177  if (additional->isAttributeCarrierSelected()) {
2178  additional->unselectAttributeCarrier(false);
2179  }
2180  // update view
2181  update();
2182  // additionals has to be saved
2184  }
2185 }
2186 
2187 
2188 // ===========================================================================
2189 // private
2190 // ===========================================================================
2191 
2192 void
2194  // init junctions (by default Crossing and walking areas aren't created)
2195  NBNodeCont& nodeContainer = myNetBuilder->getNodeCont();
2196  for (auto name_it : nodeContainer.getAllNames()) {
2197  NBNode* nbn = nodeContainer.retrieve(name_it);
2198  registerJunction(new GNEJunction(*nbn, this, true));
2199  }
2200 
2201  // init edges
2203  for (auto name_it : ec.getAllNames()) {
2204  NBEdge* nbe = ec.retrieve(name_it);
2205  registerEdge(new GNEEdge(*nbe, this, false, true));
2206  if (myGrid.getWidth() > 10e16 || myGrid.getHeight() > 10e16) {
2207  throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
2208  }
2209  }
2210 
2211  // make sure myGrid is initialized even for an empty net
2212  if (myAttributeCarriers.edges.size() == 0) {
2213  myGrid.add(Boundary(0, 0, 100, 100));
2214  }
2215 
2216  // sort nodes edges so that arrows can be drawn correctly
2217  NBNodesEdgesSorter::sortNodesEdges(nodeContainer);
2218 }
2219 
2220 
2221 void
2223  myNetBuilder->getNodeCont().insert(junction->getNBNode());
2224  registerJunction(junction);
2225 }
2226 
2227 
2228 void
2230  NBEdge* nbe = edge->getNBEdge();
2231  myNetBuilder->getEdgeCont().insert(nbe); // should we ignore pruning double edges?
2232  // if this edge was previouls extracted from the edgeContainer we have to rewire the nodes
2233  nbe->getFromNode()->addOutgoingEdge(nbe);
2234  nbe->getToNode()->addIncomingEdge(nbe);
2235  registerEdge(edge);
2236 }
2237 
2238 
2239 GNEJunction*
2241  // increase reference
2242  junction->incRef("GNENet::registerJunction");
2243  junction->setResponsible(false);
2244  myAttributeCarriers.junctions[junction->getMicrosimID()] = junction;
2245  // add it into grid
2246  myGrid.add(junction->getBoundary());
2247  myGrid.addAdditionalGLObject(junction);
2248  // update geometry
2249  junction->updateGeometry(true);
2250  // check if junction is selected
2251  if (junction->isAttributeCarrierSelected()) {
2252  junction->selectAttributeCarrier(false);
2253  }
2254  // @todo let Boundary class track z-coordinate natively
2255  const double z = junction->getNBNode()->getPosition().z();
2256  if (z != 0) {
2258  }
2259  update();
2260  return junction;
2261 }
2262 
2263 
2264 GNEEdge*
2266  edge->incRef("GNENet::registerEdge");
2267  edge->setResponsible(false);
2268  // add edge to internal container of GNENet
2269  myAttributeCarriers.edges[edge->getMicrosimID()] = edge;
2270  // add edge to grid
2271  myGrid.add(edge->getBoundary());
2273  // check if edge is selected
2274  if (edge->isAttributeCarrierSelected()) {
2275  edge->selectAttributeCarrier(false);
2276  }
2277  // Add references into GNEJunctions
2280  // update view
2281  update();
2282  return edge;
2283 }
2284 
2285 
2286 void
2288  // remove it from Inspector Frame
2290  // Remove from grid and container
2291  myGrid.removeAdditionalGLObject(junction);
2292  // check if junction is selected
2293  if (junction->isAttributeCarrierSelected()) {
2294  junction->unselectAttributeCarrier(false);
2295  }
2296  myAttributeCarriers.junctions.erase(junction->getMicrosimID());
2297  myNetBuilder->getNodeCont().extract(junction->getNBNode());
2298  junction->decRef("GNENet::deleteSingleJunction");
2299  junction->setResponsible(true);
2300  update();
2301 }
2302 
2303 
2304 void
2306  // remove it from Inspector Frame
2308  // remove edge from visual grid and container
2310  // check if junction is selected
2311  if (edge->isAttributeCarrierSelected()) {
2312  edge->unselectAttributeCarrier(false);
2313  }
2314  myAttributeCarriers.edges.erase(edge->getMicrosimID());
2315  // extract edge of district container
2317  edge->decRef("GNENet::deleteSingleEdge");
2318  edge->setResponsible(true);
2319  // Remove refrences from GNEJunctions
2322  // invalidate junction logic
2323  update();
2324 }
2325 
2326 
2327 void
2329  // add shape depending of their type and if is selected
2330  if (shape->getTag() == SUMO_TAG_POLY) {
2331  GUIPolygon* poly = dynamic_cast<GUIPolygon*>(shape);
2333  myPolygons.add(shape->getID(), poly);
2334  } else {
2335  GUIPointOfInterest* poi = dynamic_cast<GUIPointOfInterest*>(shape);
2337  myPOIs.add(shape->getID(), poi);
2338 
2339  }
2340  // check if shape has to be selected
2341  if (shape->isAttributeCarrierSelected()) {
2342  shape->selectAttributeCarrier(false);
2343  }
2344  // POILanes has to be added from lane
2345  if (shape->getTag() == SUMO_TAG_POILANE) {
2346  retrieveLane(shape->getAttribute(SUMO_ATTR_LANE))->addShapeChild(shape);
2347  }
2348  // insert shape requieres always save shapes
2349  requiereSaveShapes(true);
2350  // update view
2351  myViewNet->update();
2352 }
2353 
2354 
2355 void
2357  // remove it from Inspector Frame
2359  if (shape->getTag() == SUMO_TAG_POLY) {
2360  GUIPolygon* poly = dynamic_cast<GUIPolygon*>(shape);
2362  myPolygons.remove(shape->getID(), false);
2363  } else {
2364  GUIPointOfInterest* poi = dynamic_cast<GUIPointOfInterest*>(shape);
2366  myPOIs.remove(shape->getID(), false);
2367  }
2368  // check if shape has to be unselected
2369  if (shape->isAttributeCarrierSelected()) {
2370  shape->unselectAttributeCarrier(false);
2371  }
2372  // POILanes has to be removed from lane
2373  if (shape->getTag() == SUMO_TAG_POILANE) {
2374  retrieveLane(shape->getAttribute(SUMO_ATTR_LANE))->removeShapeChild(shape);
2375  }
2376  // remove shape requires always save shapes
2377  requiereSaveShapes(true);
2378  // update view
2379  myViewNet->update();
2380 }
2381 
2382 
2383 void
2385  if (myViewNet) {
2386  myViewNet->update();
2387  }
2388 }
2389 
2390 
2391 void
2392 GNENet::reserveEdgeID(const std::string& id) {
2393  myEdgeIDSupplier.avoid(id);
2394 }
2395 
2396 
2397 void
2398 GNENet::reserveJunctionID(const std::string& id) {
2400 }
2401 
2402 
2403 void
2405  for (auto it : myAttributeCarriers.edges) {
2406  it.second->remakeGNEConnections();
2407  }
2408  for (auto it : myAttributeCarriers.edges) {
2409  it.second->updateGeometry(true);
2410  }
2411 }
2412 
2413 
2414 void
2415 GNENet::computeAndUpdate(OptionsCont& oc, bool volatileOptions) {
2416  // make sure we only add turn arounds to edges which currently exist within the network
2417  std::set<std::string> liveExplicitTurnarounds;
2418  for (auto it : myExplicitTurnarounds) {
2419  if (myAttributeCarriers.edges.count(it) > 0) {
2420  liveExplicitTurnarounds.insert(it);
2421  }
2422  }
2423 
2424  // removes all junctions of grid
2425  for (const auto& it : myAttributeCarriers.junctions) {
2426  myGrid.removeAdditionalGLObject(it.second);
2427  }
2428 
2429  // remove all edges from grid
2430  for (const auto& it : myAttributeCarriers.edges) {
2431  myGrid.removeAdditionalGLObject(it.second);
2432  }
2433 
2434  myNetBuilder->compute(oc, liveExplicitTurnarounds, volatileOptions);
2435  // update ids if necessary
2436  if (oc.getBool("numerical-ids") || oc.isSet("reserved-ids")) {
2437  std::map<std::string, GNEEdge*> newEdgeMap;
2438  std::map<std::string, GNEJunction*> newJunctionMap;
2439  // fill newEdgeMap
2440  for (auto it : myAttributeCarriers.edges) {
2441  it.second->setMicrosimID(it.second->getNBEdge()->getID());
2442  newEdgeMap[it.second->getNBEdge()->getID()] = it.second;
2443  }
2444  for (auto it : myAttributeCarriers.junctions) {
2445  newJunctionMap[it.second->getNBNode()->getID()] = it.second;
2446  it.second->setMicrosimID(it.second->getNBNode()->getID());
2447  }
2448  myAttributeCarriers.edges = newEdgeMap;
2449  myAttributeCarriers.junctions = newJunctionMap;
2450  }
2451  // update rtree if necessary
2452  if (!oc.getBool("offset.disable-normalization")) {
2453  for (auto it : myAttributeCarriers.edges) {
2454  // refresh edge geometry
2455  it.second->updateGeometry(true);
2456  }
2457  }
2458  // Clear current inspected ACs in inspectorFrame if a previous net was loaded
2459  if (myViewNet != 0) {
2461  }
2462  // Remove from container
2463  myGrid.reset();
2464  myGrid.add(GeoConvHelper::getFinal().getConvBoundary());
2465 
2466  // if volatile options are true
2467  if (volatileOptions) {
2468  assert(myViewNet != 0);
2469 
2470  // clear undo list (This will be remove additionals and shapes)
2471  myViewNet->getUndoList()->clear();
2472 
2473  // remove all edges of net (It was already removed from grid)
2474  auto copyOfEdges = myAttributeCarriers.edges;
2475  for (auto it : copyOfEdges) {
2476  myAttributeCarriers.edges.erase(it.second->getMicrosimID());
2477  }
2478 
2479  // removes all junctions of net (It was already removed from grid)
2480  auto copyOfJunctions = myAttributeCarriers.junctions;
2481  for (auto it : copyOfJunctions) {
2482  myAttributeCarriers.junctions.erase(it.second->getMicrosimID());
2483  }
2484 
2485  // clear rest of additionals and shapes that weren't removed during cleaning of undo list
2486  for (const auto& it : myAttributeCarriers.additionals) {
2487  for (const auto& j : it.second) {
2488  // only remove drawable additionals
2489  if (GNEAttributeCarrier::getTagProperties(j.second->getTag()).isDrawable()) {
2490  myGrid.removeAdditionalGLObject(j.second);
2491  }
2492  }
2493  }
2495 
2496  // clear rest of polygons that weren't removed during cleaning of undo list
2497  for (const auto& it : myPolygons) {
2498  myGrid.removeAdditionalGLObject(dynamic_cast<GUIGlObject*>(it.second));
2499  }
2500  myPolygons.clear();
2501 
2502  // clear rest of POIs that weren't removed during cleaning of undo list
2503  for (const auto& it : myPOIs) {
2504  myGrid.removeAdditionalGLObject(dynamic_cast<GUIGlObject*>(it.second));
2505  }
2506  myPOIs.clear();
2507 
2508  // init again junction an edges (Additionals and shapes will be loaded after the end of this function)
2510 
2511  } else {
2512  // remake connections
2513  for (auto it : myAttributeCarriers.edges) {
2514  it.second->remakeGNEConnections();
2515  }
2516 
2517  // iterate over junctions of net
2518  for (const auto& it : myAttributeCarriers.junctions) {
2519  // undolist may not yet exist but is also not needed when just marking junctions as valid
2520  it.second->setLogicValid(true, 0);
2521  // insert junction in grid again
2522  myGrid.addAdditionalGLObject(it.second);
2523  // updated geometry
2524  it.second->updateGeometry(true);
2525  }
2526 
2527  // iterate over all edges of net
2528  for (const auto& it : myAttributeCarriers.edges) {
2529  // insert edge in grid again
2530  myGrid.addAdditionalGLObject(it.second);
2531  // update geometry
2532  it.second->updateGeometry(true);
2533  }
2534  }
2535 
2536  // net recomputed, then return false;
2537  myNeedRecompute = false;
2538 }
2539 
2540 
2541 void
2542 GNENet::replaceInListAttribute(GNEAttributeCarrier* ac, SumoXMLAttr key, const std::string& which, const std::string& by, GNEUndoList* undoList) {
2543  assert(GNEAttributeCarrier::getTagProperties(ac->getTag()).getAttribute(key).isList());
2544  std::vector<std::string> values = GNEAttributeCarrier::parse<std::vector<std::string> >(ac->getAttribute(key));
2545  std::vector<std::string> newValues;
2546  for (auto v : values) {
2547  newValues.push_back(v == which ? by : v);
2548  }
2549  ac->setAttribute(key, toString(newValues), undoList);
2550 }
2551 
2552 /****************************************************************************/
void setViewNet(GNEViewNet *viewNet)
Set the viewNet to be notified of network changes.
Definition: GNENet.cpp:896
GNEJunction * splitEdge(GNEEdge *edge, const Position &pos, GNEUndoList *undoList, GNEJunction *newJunction=0)
split edge at position by inserting a new junction
Definition: GNENet.cpp:680
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:702
void enableSaveTLSProgramsMenu()
enable save TLS Programs
bool addRestrictedLane(SUMOVehicleClass vclass, GNEEdge &edge, int index, GNEUndoList *undoList)
add restricted lane to edge
Definition: GNENet.cpp:647
std::vector< GNEJunction * > retrieveJunctions(bool onlySelected=false)
return all junctions
Definition: GNENet.cpp:1107
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:2193
void insertAdditional(GNEAdditional *additional)
Insert a additional element int GNENet container.
Definition: GNENet.cpp:2140
std::vector< GNELane * > retrieveLanes(bool onlySelected=false)
return all lanes
Definition: GNENet.cpp:1059
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:915
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:1401
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:1407
void setMicrosimID(const std::string &newID)
override to also set lane ids
Definition: GNEEdge.cpp:1545
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:1181
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:2356
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:974
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:961
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:757
void update()
notify myViewNet
Definition: GNENet.cpp:2384
void insertJunction(GNEJunction *junction)
inserts a single junction into the net and into the underlying netbuild-container ...
Definition: GNENet.cpp:2222
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:259
void 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:948
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:1711
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:994
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:1783
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:1553
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:1828
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:2229
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:1204
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:1751
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
first coordinate of edge shape
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
void addOutgoingEdge(NBEdge *edge)
adds an outgoing edge
Definition: NBNode.cpp: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:2240
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:256
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:1390
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:2119
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:2022
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:1771
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:1795
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:767
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:1840
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:1667
bool removeRestrictedLane(SUMOVehicleClass vclass, GNEEdge &edge, GNEUndoList *undoList)
remove restricted lane
Definition: GNENet.cpp:666
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:1991
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:1298
void saveAdditionalsConfirmed(const std::string &filename)
save additionals after confirming invalid objects
Definition: GNENet.cpp:1923
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNELane.cpp:880
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:2328
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
std::string getLaneID(int lane) const
get Lane ID (Secure)
Definition: NBEdge.cpp:2990
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:418
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:902
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:1413
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:1175
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:1216
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:1366
void requiereSaveAdditionals(bool value)
inform that additionals has to be saved
Definition: GNENet.cpp:1854
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:61
void initGNEConnections()
initialize GNEConnections
Definition: GNENet.cpp:2404
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:870
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:2047
#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:1120
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:746
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:3299
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:1204
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:840
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:620
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:1622
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:2398
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:1217
GNECrossing * retrieveCrossing(const std::string &id, bool failHard=true) const
get Crossing by id
Definition: GNENet.cpp:1010
std::vector< std::string > getAllNames() const
get all node names
void deleteSingleJunction(GNEJunction *junction)
deletes a single junction
Definition: GNENet.cpp:2287
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:1913
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:1046
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:865
NBConnection getNBConnection() const
get NBConnection
GNEEdge * registerEdge(GNEEdge *edge)
registers an edge with GNENet containers
Definition: GNENet.cpp:2265
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:1807
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:1605
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:3166
std::vector< Position > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition: NBNode.cpp:3122
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:852
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:1294
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:1699
void computeAndUpdate(OptionsCont &oc, bool volatileOptions)
recompute the network and update lane geometries
Definition: GNENet.cpp:2415
int getNumberOfShapes() const
get number of shapes
Definition: GNENet.cpp:2103
crossing between edges for pedestrians
void renameEdge(GNEEdge *edge, const std::string &newID)
updates the map and reserves new id
Definition: GNENet.cpp:1722
static void replaceInListAttribute(GNEAttributeCarrier *ac, SumoXMLAttr key, const std::string &which, const std::string &by, GNEUndoList *undoList)
Definition: GNENet.cpp:2542
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:1030
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:1789
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:888
const std::map< std::string, GNEAdditional * > & getAdditionalByType(SumoXMLTag type) const
get map with IDs and pointers to additionals
Definition: GNENet.cpp:1822
void deleteAdditional(GNEAdditional *additional)
delete additional element of GNENet container
Definition: GNENet.cpp:2163
GNEEdge * addReversedEdge(GNEEdge *edge, GNEUndoList *undoList)
add reversed edge
Definition: GNENet.cpp:770
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:2392
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:432
void deleteSingleEdge(GNEEdge *edge)
deletes a single edge
Definition: GNENet.cpp:2305
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:2008
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:805
void requiereSaveTLSPrograms()
Definition: GNENet.cpp:2109
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:930
void addGLObjectIntoGrid(GUIGlObject *o)
add GL Object into net
Definition: GNENet.cpp:1168
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:1074
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:827
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:1735
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition: GNENet.cpp:1765
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:2134
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:439
void saveAdditionals(const std::string &filename)
save additional elements of the network
Definition: GNENet.cpp:1873
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:880
void requireRecompute()
inform the net about the need for recomputation
Definition: GNENet.cpp:1384
bool isNetSaved() const
return if net has to be saved
Definition: GNENet.cpp:864
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:2065
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:1745
void saveShapes(const std::string &filename)
save shapes elements of the network
Definition: GNENet.cpp:2082
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.