Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNENet.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// A visual container for GNE-network-components such as GNEEdge and GNEJunction.
19// GNE components wrap netbuild-components and supply visualisation and editing
20// capabilities (adapted from GUINet)
21//
22// WorkrouteFlow (rough draft)
23// use NILoader to fill
24// do netedit stuff
25// call compute to save results
26//
27/****************************************************************************/
55#include <netwrite/NWFrame.h>
64
66#include "GNENet.h"
67#include "GNEViewNet.h"
68#include "GNEUndoList.h"
69#include "GNEViewParent.h"
70
71
72// ===========================================================================
73// FOX callback mapping
74// ===========================================================================
75
76FXIMPLEMENT_ABSTRACT(GNENetHelper::GNEChange_ReplaceEdgeInTLS, GNEChange, nullptr, 0)
77
78// ===========================================================================
79// static members
80// ===========================================================================
81
82const double GNENet::Z_INITIALIZED = 1;
83const std::map<SumoXMLAttr, std::string> GNENet::EMPTY_HEADER;
84
85// ===========================================================================
86// member method definitions
87// ===========================================================================
88
89GNENet::GNENet(NBNetBuilder* netBuilder) :
90 GUIGlObject(GLO_NETWORK, "", nullptr),
91 myNetBuilder(netBuilder),
92 myAttributeCarriers(new GNENetHelper::AttributeCarriers(this)),
93 mySavingStatus(new GNENetHelper::SavingStatus()),
94 myNetworkPathManager(new GNEPathManager(this)),
95 myDemandPathManager(new GNEPathManager(this)) {
96 // set net in gIDStorage
98 // Write GL debug information
99 WRITE_GLDEBUG("initJunctionsAndEdges function called in GNENet constructor");
100 // init junction and edges
101 initJunctionsAndEdges();
102 // check Z boundary
103 if (myZBoundary.ymin() != Z_INITIALIZED) {
104 myZBoundary.add(0, 0);
105 }
106
107}
108
109
111 // delete path managers
113 delete myDemandPathManager;
114 // delete AttributeCarriers
115 delete myAttributeCarriers;
116 // delete saving status
117 delete mySavingStatus;
118 // show extra information for tests
119 WRITE_DEBUG("Deleting net builder in GNENet destructor");
120 delete myNetBuilder;
121}
122
123
128
129
132 return mySavingStatus;
133}
134
135
140
145
146
147const Boundary&
149 // SUMORTree is also a Boundary
150 return myGrid;
151}
152
153
156 return myGrid;
157}
158
159const std::map<std::string, int>&
163
164
167 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
168 buildPopupHeader(ret, app);
170 buildPositionCopyEntry(ret, app);
171 if (GeoConvHelper::getFinal().usingGeoProjection()) {
172 GUIDesigns::buildFXMenuCommand(ret, TL("Copy view geo-boundary to clipboard"), nullptr, ret, MID_COPY_VIEW_GEOBOUNDARY);
173 }
174 return ret;
175}
176
177
180 // Nets lanes don't have attributes
182 // close building
183 ret->closeBuilding();
184 return ret;
185}
186
187
188void
190 // draw boundaries
192}
193
194
197 return getBoundary();
198}
199
200
201void
202GNENet::expandBoundary(const Boundary& newBoundary) {
203 myGrid.add(newBoundary);
204}
205
206
207const Boundary&
209 return myZBoundary;
210}
211
212
213void
215 // @todo let Boundary class track z-coordinate natively
216 if (z != 0) {
218 }
219}
220
221
224 // get junction prefix
225 const std::string junctionPrefix = OptionsCont::getOptions().getString("prefix") + OptionsCont::getOptions().getString("node-prefix");
226 // generate new ID
227 while (myAttributeCarriers->getJunctions().count(junctionPrefix + toString(myJunctionIDCounter)) != 0) {
229 }
230 // create new NBNode
231 NBNode* nbn = new NBNode(junctionPrefix + toString(myJunctionIDCounter), pos);
232 GNEJunction* junction = new GNEJunction(this, nbn);
233 undoList->add(new GNEChange_Junction(junction, true), true);
234 return junction;
235}
236
237
238GNEEdge*
239GNENet::createEdge(GNEJunction* src, GNEJunction* dest, GNEEdge* edgeTemplate, GNEUndoList* undoList,
240 const std::string& suggestedName, bool wasSplit, bool allowDuplicateGeom, bool recomputeConnections) {
241 // get edge prefix
242 const std::string edgePrefix = OptionsCont::getOptions().getString("prefix") + OptionsCont::getOptions().getString("edge-prefix");
243 // get edge infix
244 std::string edgeInfix = OptionsCont::getOptions().getString("edge-infix");
245 // prevent duplicate edge (same geometry)
246 for (const auto& outgoingEdge : src->getNBNode()->getOutgoingEdges()) {
247 if (outgoingEdge->getToNode() == dest->getNBNode() && outgoingEdge->getGeometry().size() == 2) {
248 if (!allowDuplicateGeom) {
249 return nullptr;
250 }
251 }
252 }
253 // check if exist opposite edge
254 const auto oppositeEdges = myAttributeCarriers->retrieveEdges(dest, src);
255 // declare edge id
256 std::string edgeID;
257 // update id
258 if (oppositeEdges.size() > 0) {
259 // avoid ids with "--..."
260 if ((oppositeEdges.front()->getID().size() > 1) && (oppositeEdges.front()->getID().front() == '-')) {
261 edgeID = oppositeEdges.front()->getID().substr(1);
262 } else {
263 edgeID = "-" + oppositeEdges.front()->getID();
264 }
265 // check if already exist an edge with edgeID
266 if (myAttributeCarriers->getEdges().count(edgeID) > 0) {
267 int counter = 0;
268 // generate new ID using edgeID and counter
269 while (myAttributeCarriers->getEdges().count(edgeID + toString(counter)) > 0) {
270 counter++;
271 }
272 edgeID = edgeID + toString(counter);
273 }
274 } else if ((suggestedName.size() > 0) && (myAttributeCarriers->retrieveEdge(suggestedName, false) == nullptr)) {
275 edgeID = suggestedName;
276 } else if (edgeInfix.size() > 0) {
277 // permit empty infix by setting it to <SPACE>
278 edgeInfix = StringUtils::trim(edgeInfix);
279 // check if exist edge with id <fromNodeID><infix><toNodeID>
280 if (myAttributeCarriers->getEdges().count(src->getID() + edgeInfix + dest->getID()) == 0) {
281 edgeID = src->getID() + edgeInfix + dest->getID();
282 } else {
283 int counter = 0;
284 // generate new ID using edgeInfix and counter
285 while (myAttributeCarriers->getEdges().count(src->getID() + edgeInfix + toString(counter) + dest->getID()) != 0) {
287 }
288 edgeID = src->getID() + edgeInfix + toString(counter) + dest->getID();
289 }
290 } else {
291 // generate new ID
292 while (myAttributeCarriers->getEdges().count(edgePrefix + toString(myEdgeIDCounter)) != 0) {
294 }
295 edgeID = edgePrefix + toString(myEdgeIDCounter);
296 }
297 GNEEdge* edge;
298 // check if there is a template edge
299 if (edgeTemplate) {
300 // create NBEdgeTemplate
301 NBEdge* nbe = new NBEdge(edgeID, src->getNBNode(), dest->getNBNode(), edgeTemplate->getNBEdge());
302 edge = new GNEEdge(this, nbe, wasSplit);
303 } else {
304 // default if no template is given
305 const auto& neteditOptions = OptionsCont::getOptions();
306 double defaultSpeed = neteditOptions.getFloat("default.speed");
307 const std::string defaultType = neteditOptions.getString("default.type");
308 const int defaultNrLanes = neteditOptions.getInt("default.lanenumber");
309 const int defaultPriority = neteditOptions.getInt("default.priority");
310 const double defaultWidth = NBEdge::UNSPECIFIED_WIDTH;
311 const double defaultOffset = NBEdge::UNSPECIFIED_OFFSET;
313 // build NBEdge
314 NBEdge* nbe = new NBEdge(edgeID, src->getNBNode(), dest->getNBNode(),
315 defaultType, defaultSpeed, NBEdge::UNSPECIFIED_FRICTION,
316 defaultNrLanes, defaultPriority,
317 defaultWidth, defaultOffset, spread);
318 // create edge
319 edge = new GNEEdge(this, nbe, wasSplit);
320 }
321 // add edge using undo list
322 undoList->begin(edge, TL("create edge"));
323 undoList->add(new GNEChange_Edge(edge, true), true);
324 // recompute connection
325 if (recomputeConnections) {
326 src->setLogicValid(false, undoList);
327 dest->setLogicValid(false, undoList);
328 }
330 undoList->end();
331 return edge;
332}
333
334
335void
337 if (networkElement->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
338 // get junction (note: could be already removed if is a child, then hardfail=false)
339 GNEJunction* junction = myAttributeCarriers->retrieveJunction(networkElement->getID(), false);
340 // if exist, remove it
341 if (junction) {
342 deleteJunction(junction, undoList);
343 }
344 } else if (networkElement->getTagProperty().getTag() == SUMO_TAG_CROSSING) {
345 // get crossing (note: could be already removed if is a child, then hardfail=false)
346 GNECrossing* crossing = myAttributeCarriers->retrieveCrossing(networkElement->getGUIGlObject(), false);
347 // if exist, remove it
348 if (crossing) {
349 deleteCrossing(crossing, undoList);
350 }
351 } else if (networkElement->getTagProperty().getTag() == SUMO_TAG_EDGE) {
352 // get edge (note: could be already removed if is a child, then hardfail=false)
353 GNEEdge* edge = myAttributeCarriers->retrieveEdge(networkElement->getID(), false);
354 // if exist, remove it
355 if (edge) {
356 deleteEdge(edge, undoList, false);
357 }
358 } else if (networkElement->getTagProperty().getTag() == SUMO_TAG_LANE) {
359 // get lane (note: could be already removed if is a child, then hardfail=false)
360 GNELane* lane = myAttributeCarriers->retrieveLane(networkElement->getGUIGlObject(), false);
361 // if exist, remove it
362 if (lane) {
363 deleteLane(lane, undoList, false);
364 }
365 } else if (networkElement->getTagProperty().getTag() == SUMO_TAG_CONNECTION) {
366 // get connection (note: could be already removed if is a child, then hardfail=false)
367 GNEConnection* connection = myAttributeCarriers->retrieveConnection(networkElement->getGUIGlObject(), false);
368 // if exist, remove it
369 if (connection) {
370 deleteConnection(connection, undoList);
371 }
372 }
373}
374
375
376void
378 // we have to delete all incident edges because they cannot exist without that junction
379 // all deletions must be undone/redone together so we start a new command group
380 // @todo if any of those edges are dead-ends should we remove their orphan junctions as well?
381 undoList->begin(GUIIcon::MODEDELETE, TL("delete junction"));
382 // invalidate junction path elements
385 // delete junction child demand elements
386 while (junction->getChildDemandElements().size() > 0) {
387 deleteDemandElement(junction->getChildDemandElements().front(), undoList);
388 }
389 // delete all crossings vinculated with junction
390 while (junction->getGNECrossings().size() > 0) {
391 deleteCrossing(junction->getGNECrossings().front(), undoList);
392 }
393 // find all crossings of neighbour junctions that shares an edge of this junction
394 std::vector<GNECrossing*> crossingsToRemove;
395 std::vector<GNEJunction*> junctionNeighbours = junction->getJunctionNeighbours();
396 for (const auto& junctionNeighbour : junctionNeighbours) {
397 // iterate over crossing of neighbour junction
398 for (const auto& crossing : junctionNeighbour->getGNECrossings()) {
399 // if at least one of the edges of junction to remove belongs to a crossing of the neighbour junction, delete it
400 if (crossing->checkEdgeBelong(junctionNeighbour->getChildEdges())) {
401 crossingsToRemove.push_back(crossing);
402 }
403 }
404 }
405 // delete collected crossings
406 for (const auto& crossing : crossingsToRemove) {
407 deleteCrossing(crossing, undoList);
408 }
409 // deleting edges changes in the underlying EdgeVector so we have to make a copy
410 const EdgeVector incidentEdges = junction->getNBNode()->getEdges();
411 for (const auto& edge : incidentEdges) {
412 deleteEdge(myAttributeCarriers->getEdges().at(edge->getID()), undoList, true);
413 }
414 // remove any traffic lights from the traffic light container (avoids lots of warnings)
416 // delete edge
417 undoList->add(new GNEChange_Junction(junction, false), true);
418 undoList->end();
419}
420
421
422void
423GNENet::deleteEdge(GNEEdge* edge, GNEUndoList* undoList, bool recomputeConnections) {
424 undoList->begin(GUIIcon::MODEDELETE, TL("delete edge"));
425 // iterate over lanes
426 for (const auto& lane : edge->getLanes()) {
427 // invalidate lane path elements
430 // delete lane additionals
431 while (lane->getChildAdditionals().size() > 0) {
432 deleteAdditional(lane->getChildAdditionals().front(), undoList);
433 }
434 // delete lane demand elements
435 while (lane->getChildDemandElements().size() > 0) {
436 deleteDemandElement(lane->getChildDemandElements().front(), undoList);
437 }
438 // delete lane generic data elements
439 while (lane->getChildGenericDatas().size() > 0) {
440 deleteGenericData(lane->getChildGenericDatas().front(), undoList);
441 }
442 }
443 // delete edge child additionals
444 while (edge->getChildAdditionals().size() > 0) {
445 deleteAdditional(edge->getChildAdditionals().front(), undoList);
446 }
447 // delete edge child demand elements
448 while (edge->getChildDemandElements().size() > 0) {
449 // special case for embedded routes
450 if (edge->getChildDemandElements().front()->getTagProperty().getTag() == GNE_TAG_ROUTE_EMBEDDED) {
451 deleteDemandElement(edge->getChildDemandElements().front()->getParentDemandElements().front(), undoList);
452 } else if (edge->getChildDemandElements().front()->getTagProperty().isPlan()) {
453 const auto planParent = edge->getChildDemandElements().front()->getParentDemandElements().front();
454 // if this is the last person child, remove plan parent (person/container) instead plan element
455 if (planParent->getChildDemandElements().size() == 1) {
456 deleteDemandElement(planParent, undoList);
457 } else {
458 deleteDemandElement(edge->getChildDemandElements().front(), undoList);
459 }
460 } else {
461 deleteDemandElement(edge->getChildDemandElements().front(), undoList);
462 }
463 }
464 // delete edge child generic datas
465 while (edge->getChildGenericDatas().size() > 0) {
466 deleteGenericData(edge->getChildGenericDatas().front(), undoList);
467 }
468 // remove edge from crossings related with this edge
469 edge->getFromJunction()->removeEdgeFromCrossings(edge, undoList);
470 edge->getToJunction()->removeEdgeFromCrossings(edge, undoList);
471 // update affected connections
472 if (recomputeConnections) {
473 edge->getFromJunction()->setLogicValid(false, undoList);
474 edge->getToJunction()->setLogicValid(false, undoList);
475 } else {
476 edge->getFromJunction()->removeConnectionsTo(edge, undoList, true);
477 edge->getToJunction()->removeConnectionsFrom(edge, undoList, true);
478 }
479 // if junction source is a TLS and after deletion will have only an edge, remove TLS
480 if (edge->getFromJunction()->getNBNode()->isTLControlled() && (edge->getFromJunction()->getGNEOutgoingEdges().size() <= 1)) {
482 }
483 // if junction destination is a TLS and after deletion will have only an edge, remove TLS
484 if (edge->getToJunction()->getNBNode()->isTLControlled() && (edge->getToJunction()->getGNEIncomingEdges().size() <= 1)) {
486 }
487 // Delete edge
488 undoList->add(new GNEChange_Edge(edge, false), true);
489 // remove edge requires always a recompute (due geometry and connections)
491 // finish delete edge
492 undoList->end();
493}
494
495
496void
498 undoList->begin(which, TL("replace edge"));
500 // iterate over lane
501 for (const auto& lane : which->getLanes()) {
502 // replace in additionals
503 std::vector<GNEAdditional*> copyOfLaneAdditionals = lane->getChildAdditionals();
504 for (const auto& additional : copyOfLaneAdditionals) {
505 GNEChange_Attribute::changeAttribute(additional, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex()), undoList);
506 if (additional->hasAttribute(SUMO_ATTR_STARTPOS)) {
508 toString(StringUtils::toDouble(additional->getAttribute(SUMO_ATTR_STARTPOS)) + which->getNBEdge()->getFinalLength()),
509 undoList);
510 }
511 if (additional->hasAttribute(SUMO_ATTR_ENDPOS)) {
513 toString(StringUtils::toDouble(additional->getAttribute(SUMO_ATTR_ENDPOS)) + which->getNBEdge()->getFinalLength()),
514 undoList);
515 }
516 }
517 // replace in demand elements
518 std::vector<GNEDemandElement*> copyOfLaneDemandElements = lane->getChildDemandElements();
519 for (const auto& demandElement : copyOfLaneDemandElements) {
520 GNEChange_Attribute::changeAttribute(demandElement, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex()), undoList);
521 }
522 // replace in generic datas
523 std::vector<GNEGenericData*> copyOfLaneGenericDatas = lane->getChildGenericDatas();
524 for (const auto& demandElement : copyOfLaneGenericDatas) {
525 GNEChange_Attribute::changeAttribute(demandElement, SUMO_ATTR_LANE, by->getNBEdge()->getLaneID(lane->getIndex()), undoList);
526 }
527 }
528 // replace in edge additionals children
529 std::vector<GNEAdditional*> addElements = which->getChildAdditionals();
530 for (GNEAdditional* add : addElements) {
531 if (add->hasAttribute(SUMO_ATTR_EDGE)) {
533 }
534 }
535 // replace in edge demand elements children
536 const std::vector<GNEDemandElement*> demandElements = which->getChildDemandElements();
537 for (GNEDemandElement* demandElement : demandElements) {
538 if (demandElement->hasAttribute(SUMO_ATTR_EDGE)) {
539 GNEChange_Attribute::changeAttribute(demandElement, SUMO_ATTR_EDGE, by->getID(), undoList);
540 }
541 if (demandElement->hasAttribute(SUMO_ATTR_EDGES)) {
542 replaceInListAttribute(demandElement, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
543 }
544 if (demandElement->hasAttribute(SUMO_ATTR_VIA)) {
545 replaceInListAttribute(demandElement, SUMO_ATTR_VIA, which->getID(), by->getID(), undoList);
546 }
547 if (demandElement->hasAttribute(SUMO_ATTR_FROM) && demandElement->getAttribute(SUMO_ATTR_FROM) == which->getID()) {
548 GNEChange_Attribute::changeAttribute(demandElement, SUMO_ATTR_FROM, by->getID(), undoList);
549 }
550 if (demandElement->hasAttribute(SUMO_ATTR_TO) && demandElement->getAttribute(SUMO_ATTR_TO) == which->getID()) {
551 GNEChange_Attribute::changeAttribute(demandElement, SUMO_ATTR_TO, by->getID(), undoList);
552 }
553 }
554 // replace in data
555 const std::vector<GNEGenericData*> dataElements = which->getChildGenericDatas();
556 for (GNEGenericData* dataElement : dataElements) {
557 if (dataElement->hasAttribute(SUMO_ATTR_EDGE)) {
558 GNEChange_Attribute::changeAttribute(dataElement, SUMO_ATTR_EDGE, by->getID(), undoList);
559 }
560 }
561 // replace in rerouters
562 addElements = which->getParentAdditionals();
563 for (GNEAdditional* add : addElements) {
564 if (add->hasAttribute(SUMO_ATTR_EDGES)) {
565 replaceInListAttribute(add, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
566 }
567 }
568 // replace in crossings
569 for (const auto& crossing : which->getToJunction()->getGNECrossings()) {
570 // if at least one of the edges of junction to remove belongs to a crossing of the source junction, delete it
571 replaceInListAttribute(crossing, SUMO_ATTR_EDGES, which->getID(), by->getID(), undoList);
572 }
573 // fix connections (make a copy because they will be modified
574 std::vector<NBEdge::Connection> NBConnections = which->getNBEdge()->getConnections();
575 for (const auto& NBConnection : NBConnections) {
576 if (NBConnection.toEdge != nullptr) {
577 undoList->add(new GNEChange_Connection(which, NBConnection, false, false), true);
578 undoList->add(new GNEChange_Connection(by, NBConnection, false, true), true);
579 }
580 }
581 undoList->add(new GNENetHelper::GNEChange_ReplaceEdgeInTLS(getTLLogicCont(), which->getNBEdge(), by->getNBEdge()), true);
582 // Delete edge
583 undoList->add(new GNEChange_Edge(which, false), true);
584 // finish replace edge
585 undoList->end();
586}
587
588
589void
590GNENet::deleteLane(GNELane* lane, GNEUndoList* undoList, bool recomputeConnections) {
591 GNEEdge* edge = lane->getParentEdge();
592 if (edge->getNBEdge()->getNumLanes() == 1) {
593 // remove the whole edge instead
594 deleteEdge(edge, undoList, recomputeConnections);
595 } else {
596 undoList->begin(GUIIcon::MODEDELETE, TL("delete lane"));
597 // invalidate lane path elements
600 // delete lane additional children
601 while (lane->getChildAdditionals().size() > 0) {
602 deleteAdditional(lane->getChildAdditionals().front(), undoList);
603 }
604 // delete lane demand element children
605 while (lane->getChildDemandElements().size() > 0) {
606 deleteDemandElement(lane->getChildDemandElements().front(), undoList);
607 }
608 // delete lane generic data children
609 while (lane->getChildGenericDatas().size() > 0) {
610 deleteGenericData(lane->getChildGenericDatas().front(), undoList);
611 }
612 // update affected connections
613 if (recomputeConnections) {
614 edge->getFromJunction()->setLogicValid(false, undoList);
615 edge->getToJunction()->setLogicValid(false, undoList);
616 } else {
617 edge->getFromJunction()->removeConnectionsTo(edge, undoList, true, lane->getIndex());
618 edge->getToJunction()->removeConnectionsFrom(edge, undoList, true, lane->getIndex());
619 }
620 // delete lane
621 const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
622 undoList->add(new GNEChange_Lane(edge, lane, laneAttrs, false, recomputeConnections), true);
623 // remove lane requires always a recompute (due geometry and connections)
625 undoList->end();
626 }
627}
628
629
630void
632 undoList->begin(GUIIcon::MODEDELETE, TL("delete connection"));
633 // obtain NBConnection to remove
634 NBConnection deleted = connection->getNBConnection();
635 GNEJunction* junctionDestination = connection->getEdgeFrom()->getToJunction();
636 junctionDestination->markAsModified(undoList);
637 undoList->add(new GNEChange_Connection(connection->getEdgeFrom(), connection->getNBEdgeConnection(), connection->isAttributeCarrierSelected(), false), true);
638 junctionDestination->invalidateTLS(undoList, deleted);
639 // remove connection requires always a recompute (due geometry and connections)
641 undoList->end();
642}
643
644
645void
647 undoList->begin(GUIIcon::MODEDELETE, TL("delete crossing"));
648 // remove it using GNEChange_Crossing
649 undoList->add(new GNEChange_Crossing(
650 crossing->getParentJunction(), crossing->getNBCrossing()->edges,
651 crossing->getNBCrossing()->width, crossing->getNBCrossing()->priority,
652 crossing->getNBCrossing()->customTLIndex,
653 crossing->getNBCrossing()->customTLIndex2,
654 crossing->getNBCrossing()->customShape,
655 crossing->isAttributeCarrierSelected(),
656 false), true);
657 // remove crossing requires always a recompute (due geometry and connections)
659 undoList->end();
660}
661
662
663void
665 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + additional->getTagStr());
666 // remove all demand element children of this additional deleteDemandElement this function recursively
667 while (additional->getChildDemandElements().size() > 0) {
668 deleteDemandElement(additional->getChildDemandElements().front(), undoList);
669 }
670 // remove all generic data children of this additional deleteGenericData this function recursively
671 while (additional->getChildGenericDatas().size() > 0) {
672 deleteGenericData(additional->getChildGenericDatas().front(), undoList);
673 }
674 // remove all additional children of this additional calling this function recursively
675 while (additional->getChildAdditionals().size() > 0) {
676 deleteAdditional(additional->getChildAdditionals().front(), undoList);
677 }
678 // remove additional
679 undoList->add(new GNEChange_Additional(additional, false), true);
680 undoList->end();
681}
682
683
684void
686 // check that default VTypes aren't removed
687 if ((demandElement->getTagProperty().getTag() == SUMO_TAG_VTYPE) && (GNEAttributeCarrier::parse<bool>(demandElement->getAttribute(GNE_ATTR_DEFAULT_VTYPE)))) {
688 throw ProcessError(TL("Trying to delete a default Vehicle Type"));
689 } else {
690 // check if currently is being inspected
691 if (myViewNet->isAttributeCarrierInspected(demandElement)) {
693 }
694 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + demandElement->getTagStr());
695 // remove all child additional elements of this demandElement calling this function recursively
696 while (demandElement->getChildAdditionals().size() > 0) {
697 deleteAdditional(demandElement->getChildAdditionals().front(), undoList);
698 }
699 // remove all child demand elements of this demandElement calling this function recursively
700 while (demandElement->getChildDemandElements().size() > 0) {
701 deleteDemandElement(demandElement->getChildDemandElements().front(), undoList);
702 }
703 // remove all generic data children of this additional deleteGenericData this function recursively
704 while (demandElement->getChildGenericDatas().size() > 0) {
705 deleteGenericData(demandElement->getChildGenericDatas().front(), undoList);
706 }
707 // remove demandElement
708 undoList->add(new GNEChange_DemandElement(demandElement, false), true);
709 undoList->end();
710 }
711}
712
713
714void
716 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + dataSet->getTagStr());
717 // make a copy of all generic data children
718 auto copyOfDataIntervalChildren = dataSet->getDataIntervalChildren();
719 // clear all data intervals (this will be delete also the dataSet)
720 for (const auto& dataInterval : copyOfDataIntervalChildren) {
721 deleteDataInterval(dataInterval.second, undoList);
722 }
723 undoList->end();
724}
725
726
727void
729 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + dataInterval->getTagStr());
730 // make a copy of all generic data children
731 auto copyOfGenericDataChildren = dataInterval->getGenericDataChildren();
732 // clear all generic datas (this will be delete also the data intervals)
733 for (const auto& genericData : copyOfGenericDataChildren) {
734 deleteGenericData(genericData, undoList);
735 }
736 undoList->end();
737}
738
739
740void
742 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + genericData->getTagStr());
743 // remove all child demand elements of this demandElement calling this function recursively
744 while (genericData->getChildDemandElements().size() > 0) {
745 deleteDemandElement(genericData->getChildDemandElements().front(), undoList);
746 }
747 // remove all generic data children of this additional deleteGenericData this function recursively
748 while (genericData->getChildGenericDatas().size() > 0) {
749 deleteGenericData(genericData->getChildGenericDatas().front(), undoList);
750 }
751 // get pointer to dataInterval and dataSet
752 GNEDataInterval* dataInterval = genericData->getDataIntervalParent();
753 GNEDataSet* dataSet = dataInterval->getDataSetParent();
754 // remove generic data
755 undoList->add(new GNEChange_GenericData(genericData, false), true);
756 // check if data interval is empty
757 if (dataInterval->getGenericDataChildren().empty()) {
758 // remove data interval
759 undoList->add(new GNEChange_DataInterval(genericData->getDataIntervalParent(), false), true);
760 // now check if data set is empty
761 if (dataSet->getDataIntervalChildren().empty()) {
762 // remove data set
763 undoList->add(new GNEChange_DataSet(genericData->getDataIntervalParent()->getDataSetParent(), false), true);
764 }
765 }
766 undoList->end();
767}
768
769
770void
772 undoList->begin(GUIIcon::MODEDELETE, TL("delete ") + meanData->getTagStr());
773 // remove mean data
774 undoList->add(new GNEChange_MeanData(meanData, false), true);
775 undoList->end();
776}
777
778
779void
780GNENet::duplicateLane(GNELane* lane, GNEUndoList* undoList, bool recomputeConnections) {
781 undoList->begin(lane, TL("duplicate lane"));
782 GNEEdge* edge = lane->getParentEdge();
783 const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
784 if (recomputeConnections) {
785 edge->getFromJunction()->setLogicValid(false, undoList);
786 edge->getToJunction()->setLogicValid(false, undoList);
787 }
788 GNELane* newLane = new GNELane(edge, lane->getIndex());
789 undoList->add(new GNEChange_Lane(edge, newLane, laneAttrs, true, recomputeConnections), true);
791 undoList->end();
792}
793
794
795bool
797 bool addRestriction = true;
798 if (vclass == SVC_PEDESTRIAN) {
799 GNEEdge* edge = lane->getParentEdge();
800 for (const auto& edgeLane : edge->getLanes()) {
801 if (edgeLane->isRestricted(SVC_PEDESTRIAN)) {
802 // prevent adding a 2nd sidewalk
803 addRestriction = false;
804 } else {
805 // ensure that the sidewalk is used exclusively
806 const SVCPermissions allOldWithoutPeds = edge->getNBEdge()->getPermissions(edgeLane->getIndex()) & ~SVC_PEDESTRIAN;
807 edgeLane->setAttribute(SUMO_ATTR_ALLOW, getVehicleClassNames(allOldWithoutPeds), undoList);
808 }
809 }
810 }
811 // restrict the lane
812 if (addRestriction) {
813 double width;
814 if (vclass == SVC_PEDESTRIAN) {
815 width = OptionsCont::getOptions().getFloat("default.sidewalk-width");
816 } else if (vclass == SVC_BICYCLE) {
817 width = OptionsCont::getOptions().getFloat("default.bikelane-width");
818 } else {
819 width = OptionsCont::getOptions().getFloat("default.lanewidth");
820 }
821 lane->setAttribute(SUMO_ATTR_ALLOW, toString(vclass), undoList);
822 lane->setAttribute(SUMO_ATTR_WIDTH, toString(width), undoList);
823 if ((vclass & ~SVC_PEDESTRIAN) == 0) {
824 std::vector<GNEConnection*> cons;
826 if (reguess) {
827 // remove all connections and rebuild from scratch
828 cons = lane->getParentEdge()->getGNEConnections();
829 } else {
830 // remove connections that have become invalid (pedestrians are
831 // connected via walkingareas somewhere else)
832 cons = lane->getGNEOutcomingConnections();
833 }
834 for (auto c : cons) {
835 undoList->add(new GNEChange_Connection(lane->getParentEdge(), c->getNBEdgeConnection(), false, false), true);
836 }
837 if (reguess) {
839 }
840 }
841 return true;
842 } else {
843 return false;
844 }
845}
846
847
848bool
849GNENet::addRestrictedLane(SUMOVehicleClass vclass, GNEEdge* edge, int index, GNEUndoList* undoList) {
850 // First check that edge don't have a restricted lane of the given vclass
851 for (const auto& lane : edge->getLanes()) {
852 if (lane->isRestricted(vclass)) {
853 return false;
854 }
855 }
856 // check that index is correct (index == size adds to the left of the leftmost lane)
857 const int numLanes = (int)edge->getLanes().size();
858 if (index > numLanes) {
859 return false;
860 }
861 if (index < 0) {
862 // for pedestrians and greenVerge, always index 0
863 index = 0;
864 // guess index from vclass
865 if (vclass == SVC_BICYCLE) {
866 // add bikelanes to the left of an existing sidewalk
867 index = edge->getLanes()[0]->isRestricted(SVC_PEDESTRIAN) ? 1 : 0;
868 } else if (vclass == SVC_BUS) {
869 // add greenVerge to the left of an existing sidewalk or bikeLane
870 // add busLane to the left of an existing sidewalk, bikeLane or greenVerge
871 index = 0;
872 while (index < numLanes && (edge->getNBEdge()->getPermissions(index) & ~(SVC_PEDESTRIAN | SVC_BICYCLE)) == 0) {
873 index++;
874 }
875 }
876 }
877 // duplicate selected lane
878 duplicateLane(edge->getLanes().at(MIN2(index, numLanes - 1)), undoList, true);
879 // transform the created lane
880 return restrictLane(vclass, edge->getLanes().at(index), undoList);
881}
882
883
884bool
885GNENet::addGreenVergeLane(GNEEdge* edge, int index, GNEUndoList* undoList) {
886 // check that index is correct (index == size adds to the left of the leftmost lane)
887 const int numLanes = (int)edge->getLanes().size();
888 if (index > numLanes) {
889 index = numLanes;
890 }
891 if (index < 0) {
892 index = 0;
893 }
894 // duplicate selected lane
895 duplicateLane(edge->getLanes().at(MIN2(index, numLanes - 1)), undoList, true);
896 // transform the created lane
897 return restrictLane(SVC_IGNORING, edge->getLanes().at(index), undoList);
898}
899
900
901bool
903 // iterate over lanes of edge
904 for (const auto& lane : edge->getLanes()) {
905 if (lane->isRestricted(vclass)) {
906 // Delete lane
907 deleteLane(lane, undoList, true);
908 return true;
909 }
910 }
911 return false;
912}
913
914
915std::pair<GNEJunction*, GNEEdge*>
916GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
917 // begin undo list
918 undoList->begin(edge, TL("split edge"));
919 // check if we have to create a new edge
920 if (newJunction == nullptr) {
921 newJunction = createJunction(pos, undoList);
922 }
923 // obtain edge geometry and split position
924 const PositionVector& oldEdgeGeometry = edge->getNBEdge()->getGeometry();
925 const double edgeSplitPosition = oldEdgeGeometry.nearest_offset_to_point2D(pos, false);
926 // obtain lane geometry and split position (needed for adjust additional and demand childs)
927 const PositionVector& oldLaneGeometry = edge->getLanes().front()->getLaneShape();
928 const double laneSplitPosition = oldLaneGeometry.nearest_offset_to_point2D(pos, false);
929 // split edge geometry in two new geometries using edgeSplitPosition
930 std::pair<PositionVector, PositionVector> newGeoms = oldEdgeGeometry.splitAt(edgeSplitPosition);
931 const double oldLength = oldEdgeGeometry.length();
932 const double relativeLength1 = oldLength != 0 ? newGeoms.first.length() / oldLength : 1;
933 const double relativeLength2 = oldLength != 0 ? newGeoms.second.length() / oldLength : 1;
934 // get shape end
935 const std::string shapeEnd = edge->getAttribute(GNE_ATTR_SHAPE_END);
936 // figure out the new name
937 int posBase = 0;
938 // set baseName
939 std::string baseName = edge->getMicrosimID();
940 if (edge->wasSplit()) {
941 const std::string::size_type sep_index = baseName.rfind('.');
942 // edge may have been renamed in between
943 if (sep_index != std::string::npos) {
944 std::string posString = baseName.substr(sep_index + 1);
945 if (GNEAttributeCarrier::canParse<int>(posString.c_str())) {
946 ;
947 posBase = GNEAttributeCarrier::parse<int>(posString.c_str());
948 baseName = baseName.substr(0, sep_index); // includes the .
949 }
950 }
951 }
952 baseName += '.';
953 // create a new edge from the new junction to the previous destination
954 GNEEdge* secondPart = createEdge(newJunction, edge->getToJunction(), edge,
955 undoList, baseName + toString(posBase + (int)edgeSplitPosition), true, false, false);
956 // fix connections from the split edge (must happen before changing SUMO_ATTR_TO)
957 edge->getToJunction()->replaceIncomingConnections(edge, secondPart, undoList);
958 // remove affected crossings from junction (must happen before changing SUMO_ATTR_TO)
959 std::vector<NBNode::Crossing> affectedCrossings;
960 for (GNECrossing* crossing : edge->getToJunction()->getGNECrossings()) {
961 if (crossing->checkEdgeBelong(edge)) {
962 NBNode::Crossing nbC = *crossing->getNBCrossing();
963 undoList->add(new GNEChange_Crossing(edge->getToJunction(), nbC, false), true);
964 EdgeVector newEdges;
965 for (NBEdge* nbEdge : nbC.edges) {
966 if (nbEdge == edge->getNBEdge()) {
967 newEdges.push_back(secondPart->getNBEdge());
968 } else {
969 newEdges.push_back(nbEdge);
970 }
971 }
972 nbC.edges = newEdges;
973 affectedCrossings.push_back(nbC);
974 }
975 }
976 // modify the edge so that it ends at the new junction (and all incoming connections are preserved
977 GNEChange_Attribute::changeAttribute(edge, SUMO_ATTR_TO, newJunction->getID(), undoList);
978 // set first part of geometry
979 newGeoms.first.pop_back();
980 newGeoms.first.erase(newGeoms.first.begin());
981 edge->setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
982 edge->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);
983 // set second part of geometry
984 secondPart->setAttribute(GNE_ATTR_SHAPE_END, shapeEnd, undoList);
985 newGeoms.second.pop_back();
986 newGeoms.second.erase(newGeoms.second.begin());
987 secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
988 // fix custom length
989 if (edge->getNBEdge()->hasLoadedLength()) {
990 // split in proportion to geometry lengths
991 const double loadedLength = edge->getNBEdge()->getLoadedLength();
992 edge->setAttribute(SUMO_ATTR_LENGTH, toString(relativeLength1 * loadedLength), undoList);
993 secondPart->setAttribute(SUMO_ATTR_LENGTH, toString(relativeLength2 * loadedLength), undoList);
994 }
995 // reconnect across the split
996 for (int i = 0; i < (int)edge->getLanes().size(); ++i) {
997 undoList->add(new GNEChange_Connection(edge, NBEdge::Connection(i, secondPart->getNBEdge(), i), false, true), true);
998 }
999 // re-add modified crossings
1000 for (const auto& nbC : affectedCrossings) {
1001 undoList->add(new GNEChange_Crossing(secondPart->getToJunction(), nbC, true), true);
1002 }
1003 // Split geometry of all child additional
1004 auto childAdditionals = edge->getChildAdditionals();
1005 for (const auto& additional : childAdditionals) {
1006 additional->splitEdgeGeometry(edgeSplitPosition, edge, secondPart, undoList);
1007 }
1008 // Split geometry of all child lane additional
1009 for (int i = 0; i < (int)edge->getLanes().size(); i++) {
1010 for (const auto& additional : edge->getLanes().at(i)->getChildAdditionals()) {
1011 additional->splitEdgeGeometry(laneSplitPosition, edge->getLanes().at(i), secondPart->getLanes().at(i), undoList);
1012 }
1013 }
1014 // Split geometry of all child demand elements
1015 auto childDemandElements = edge->getChildDemandElements();
1016 for (const auto& demandElement : childDemandElements) {
1017 demandElement->splitEdgeGeometry(edgeSplitPosition, edge, secondPart, undoList);
1018 }
1019 // Split geometry of all child lane demand elements
1020 for (int i = 0; i < (int)edge->getLanes().size(); i++) {
1021 for (const auto& demandElement : edge->getLanes().at(i)->getChildDemandElements()) {
1022 demandElement->splitEdgeGeometry(laneSplitPosition, edge->getLanes().at(i), secondPart->getLanes().at(i), undoList);
1023 }
1024 }
1025 // finish undo list
1026 undoList->end();
1027 // return new junction
1028 return std::make_pair(newJunction, secondPart);
1029}
1030
1031
1032void
1033GNENet::splitEdgesBidi(GNEEdge* edge, GNEEdge* oppositeEdge, const Position& pos, GNEUndoList* undoList) {
1034 GNEJunction* newJunction = nullptr;
1035 undoList->begin(edge, TL("split edges"));
1036 // split edge and save created junction
1037 auto newStuff = splitEdge(edge, pos, undoList, newJunction);
1038 newJunction = newStuff.first;
1039 // split second edge
1040 splitEdge(oppositeEdge, pos, undoList, newJunction);
1041 if (edge->getLanes().back()->getAttribute(GNE_ATTR_OPPOSITE) != "") {
1042 // restore opposite lane information
1043 for (const auto& nbEdge : newJunction->getNBNode()->getEdges()) {
1044 GNEEdge* e = myAttributeCarriers->retrieveEdge(nbEdge->getID());
1045 // store old attribute before it's changed by guess opposite
1046 e->getLanes().back()->setAttribute(GNE_ATTR_OPPOSITE, "", undoList);
1047 if (nbEdge->guessOpposite(true)) {
1048 e->getLanes().back()->setAttribute(GNE_ATTR_OPPOSITE, nbEdge->getLanes().back().oppositeID, undoList);
1049 }
1050 }
1051 }
1052 undoList->end();
1053}
1054
1055
1056void
1058 undoList->begin(edge, TL("reverse edge"));
1059 deleteEdge(edge, undoList, false); // still exists. we delete it so we can reuse the name in case of resplit
1060 GNEEdge* reversed = createEdge(edge->getToJunction(), edge->getFromJunction(), edge, undoList, edge->getID(), false, true);
1061 assert(reversed != 0);
1062 reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
1065 undoList->end();
1066}
1067
1068
1069GNEEdge*
1070GNENet::addReversedEdge(GNEEdge* edge, const bool disconnected, GNEUndoList* undoList) {
1071 GNEEdge* reversed = edge->getReverseEdge();
1072 if (reversed != nullptr) {
1073 return reversed;
1074 }
1075 undoList->begin(edge, TL("add reversed edge"));
1076 if (!disconnected) {
1077 // for rail edges, we assume bi-directional tracks are wanted
1078 reversed = createEdge(edge->getToJunction(), edge->getFromJunction(), edge, undoList, "-" + edge->getID(), false, true);
1079 assert(reversed != 0);
1080 reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList);
1083 } else {
1084 // if the edge is centered it should probably connect somewhere else
1085 // make it easy to move and reconnect it
1086 PositionVector orig = edge->getNBEdge()->getGeometry();
1087 PositionVector origInner = edge->getNBEdge()->getInnerGeometry();
1088 const double tentativeShift = edge->getNBEdge()->getTotalWidth() + 2;
1089 orig.move2side(-tentativeShift);
1090 origInner.move2side(-tentativeShift);
1091 GNEJunction* src = createJunction(orig.back(), undoList);
1092 GNEJunction* dest = createJunction(orig.front(), undoList);
1093 reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true);
1094 assert(reversed != 0);
1095 reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
1096 reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList);
1097 // select the new edge and its nodes
1098 reversed->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1099 src->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1100 dest->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1101 }
1102 undoList->end();
1103 return reversed;
1104}
1105
1106
1107void
1109 undoList->begin(moved, TL("merge junctions"));
1110 // place moved junction in the same position of target junction
1112 // deleting edges changes in the underlying EdgeVector so we have to make a copy
1113 const EdgeVector incomingNBEdges = moved->getNBNode()->getIncomingEdges();
1114 for (const auto& incomingNBEdge : incomingNBEdges) {
1115 // delete edges between the merged junctions
1116 GNEEdge* edge = myAttributeCarriers->getEdges().at(incomingNBEdge->getID());
1117 if (edge->getFromJunction() == target) {
1118 deleteEdge(edge, undoList, false);
1119 } else {
1120 GNEChange_Attribute::changeAttribute(edge, SUMO_ATTR_TO, target->getID(), undoList);
1121 }
1122 }
1123 // deleting edges changes in the underlying EdgeVector so we have to make a copy
1124 const EdgeVector outgoingNBEdges = moved->getNBNode()->getOutgoingEdges();
1125 for (const auto& outgoingNBEdge : outgoingNBEdges) {
1126 // delete edges between the merged junctions
1127 GNEEdge* edge = myAttributeCarriers->getEdges().at(outgoingNBEdge->getID());
1128 if (edge->getToJunction() == target) {
1129 deleteEdge(edge, undoList, false);
1130 } else {
1131 GNEChange_Attribute::changeAttribute(edge, SUMO_ATTR_FROM, target->getID(), undoList);
1132 }
1133 }
1134 // deleted moved junction
1135 deleteJunction(moved, undoList);
1136 undoList->end();
1137}
1138
1139
1140void
1142 for (const EdgeSet& roundabout : myNetBuilder->getEdgeCont().getRoundabouts()) {
1143 for (NBEdge* edge : roundabout) {
1144 if (edge->getFromNode() == junction->getNBNode()) {
1145 undoList->begin(junction, TL("select roundabout"));
1146 for (const auto& roundaboutEdge : roundabout) {
1147 GNEEdge* e = myAttributeCarriers->retrieveEdge(roundaboutEdge->getID());
1148 e->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1149 e->getToJunction()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1150 }
1151 undoList->end();
1152 return;
1153 }
1154 }
1155 }
1156}
1157
1158
1159void
1161 undoList->begin(junction, TL("create roundabout"));
1162 // reset shape end from incoming edges
1163 for (const auto& incomingEdge : junction->getGNEIncomingEdges()) {
1164 incomingEdge->setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
1165 }
1166 // reset shape start from outgoing edges
1167 for (const auto& outgoingEdge : junction->getGNEOutgoingEdges()) {
1168 outgoingEdge->setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
1169 }
1170 junction->getNBNode()->updateSurroundingGeometry();
1171 double radius = junction->getNBNode()->getRadius();
1172 if (radius == NBNode::UNSPECIFIED_RADIUS) {
1173 radius = OptionsCont::getOptions().getFloat("default.junctions.radius");
1174 }
1175 std::vector<GNEEdge*> edges;
1176 // use clockwise sorting
1177 for (const auto& nbEdge : junction->getNBNode()->getEdges()) {
1178 edges.push_back(myAttributeCarriers->retrieveEdge(nbEdge->getID()));
1179 }
1180 const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
1181 if (lefthand) {
1182 std::reverse(edges.begin(), edges.end());
1183 }
1184 const double lefthandSign = lefthand ? -1 : 1;
1185 std::vector<GNEJunction*> newJunctions;
1186 GNEEdge* templateEdge = nullptr;
1187 GNEEdge* prevOpposite = nullptr;
1188 // store old crossings edges as ids because edges are renamed and pointers will be invalid
1189 std::vector<std::pair<NBNode::Crossing, std::vector<std::string>>> oldCrossings;
1190 for (const auto& crossing : junction->getGNECrossings()) {
1191 std::vector<std::string> edgeIDs;
1192 for (auto e : crossing->getCrossingEdges()) {
1193 edgeIDs.push_back(e->getID());
1194 }
1195 oldCrossings.push_back(std::make_pair(*crossing->getNBCrossing(), edgeIDs));
1196 }
1197 std::map<std::string, std::string> edgeRename;
1198 // split incoming/outgoing edges
1199 for (GNEEdge* edge : edges) {
1200 GNEJunction* newJunction = nullptr;
1201 if (edge == prevOpposite) {
1202 newJunction = newJunctions.back();
1203 }
1204 // update template (most "important" incoming edge)
1205 if (edge->getToJunction() == junction) {
1206 if (templateEdge == nullptr) {
1207 templateEdge = edge;
1208 } else {
1209 NBEdge* tpl = templateEdge->getNBEdge();
1210 NBEdge* e = edge->getNBEdge();
1211 if (tpl->getNumLanes() < e->getNumLanes()
1212 || (tpl->getNumLanes() == e->getNumLanes()
1213 && tpl->getPriority() < e->getPriority())) {
1214 templateEdge = edge;
1215 }
1216 }
1217 }
1218 //std::cout << " edge=" << edge->getID() << " prevOpposite=" << Named::getIDSecure(prevOpposite) << " newJunction=" << Named::getIDSecure(newJunction) << "\n";
1219 prevOpposite = edge->getOppositeEdges().size() > 0 ? edge->getOppositeEdges().front() : nullptr;
1220 const double geomLength = edge->getNBEdge()->getGeometry().length2D();
1221 const double splitOffset = (edge->getToJunction() == junction
1222 ? MAX2(POSITION_EPS, geomLength - radius)
1223 : MIN2(geomLength - POSITION_EPS, radius));
1224 Position pos = edge->getNBEdge()->getGeometry().positionAtOffset2D(splitOffset);
1225 auto newStuff = splitEdge(edge, pos, undoList, newJunction);
1226 newJunction = newStuff.first;
1227 if (edge->getFromJunction() == junction) {
1228 // edge will be deleted and the new part after the split kept. Preserve edge id
1229 edgeRename[newStuff.second->getID()] = edge->getID();
1230 }
1231 if (newJunctions.empty() || newJunction != newJunctions.back()) {
1232 newJunctions.push_back(newJunction);
1233 }
1234 }
1235
1236 Position center = junction->getPositionInView();
1237 deleteJunction(junction, undoList);
1238 // rename edges after the originals have been deleted
1239 for (auto item : edgeRename) {
1240 GNEEdge* outgoing = myAttributeCarriers->retrieveEdge(item.first);
1241 outgoing->setAttribute(SUMO_ATTR_ID, item.second, undoList);
1242 }
1243 // restore crossings (after rename)
1244 for (auto nbCItem : oldCrossings) {
1245 for (GNEJunction* nj : newJunctions) {
1246 nbCItem.first.edges.clear();
1247 // check whether this junction has all the edges of the crossing
1248 for (const std::string& ce : nbCItem.second) {
1249 bool foundCE = false;
1250 for (NBEdge* je : nj->getNBNode()->getEdges()) {
1251 if (je->getID() == ce) {
1252 foundCE = true;
1253 nbCItem.first.edges.push_back(je);
1254 break;
1255 }
1256 }
1257 if (!foundCE) {
1258 break;
1259 }
1260 }
1261 if (nbCItem.first.edges.size() == nbCItem.second.size()) {
1262 undoList->add(new GNEChange_Crossing(nj, nbCItem.first, true), true);
1263 break;
1264 }
1265 }
1266 }
1267 // create new edges to connect roundabout junctions (counter-clockwise)
1268 const double resolution = OptionsCont::getOptions().getFloat("opendrive.curve-resolution") * 3;
1269 for (int i = 0; i < (int)newJunctions.size(); i++) {
1270 GNEJunction* from = newJunctions[(i + 1) % newJunctions.size()];
1271 GNEJunction* to = newJunctions[i];
1272 GNEEdge* newEdge = createEdge(from, to, nullptr, undoList);
1273 const double angle1 = center.angleTo2D(from->getPositionInView());
1274 const double angle2 = center.angleTo2D(to->getPositionInView());
1275 // insert geometry points every resolution meters
1276 const double angleDiff = fabs(GeomHelper::angleDiff(angle2, angle1));
1277 // circumference = 2 * M_PI * radius, angularFraction = angleDiff / 2 * M_PI
1278 int numSegments = MAX2(2, (int)ceil(angleDiff * radius / resolution));
1279 PositionVector innerGeom;
1280 for (int j = 1; j < numSegments; j++) {
1281 const double angle = angle1 + lefthandSign * j * angleDiff / numSegments;
1282 innerGeom.push_back(center + Position(cos(angle) * radius, sin(angle) * radius));
1283 }
1284 //std::cout << " newEdge=" << newEdge->getID() << " angle1=" << angle1 << " angle2=" << angle2 << " angleDiff=" << angleDiff
1285 // << " numSegments=" << numSegments << " innerGeom=" << innerGeom << "\n";
1286 newEdge->setAttribute(SUMO_ATTR_SHAPE, toString(innerGeom), undoList);
1287 if (templateEdge) {
1288 GNEEdgeTemplate t(templateEdge);
1289 newEdge->copyTemplate(&t, undoList);
1290 }
1291 }
1292 undoList->end();
1293}
1294
1295
1296bool
1298 // Check that there isn't another junction in the same position as Pos
1299 for (auto& junction : myAttributeCarriers->getJunctions()) {
1300 if (junction.second->getPositionInView() == pos) {
1301 return false;
1302 }
1303 }
1304 return true;
1305}
1306
1307
1308void
1310 auto& neteditOptions = OptionsCont::getOptions();
1311 auto& sumoOptions = myViewNet->getViewParent()->getGNEAppWindows()->getSumoOptions();
1312 // set output file in SUMO and netedit options
1313 neteditOptions.resetWritable();
1314 neteditOptions.set("output-file", neteditOptions.getString("net-file"));
1315 sumoOptions.resetWritable();
1316 sumoOptions.set("net-file", neteditOptions.getString("net-file"));
1317 // compute without volatile options and update network
1318 computeAndUpdate(neteditOptions, false);
1319 // clear typeContainer
1321 // now update typeContainer with edgeTypes
1322 for (const auto& edgeType : myAttributeCarriers->getEdgeTypes()) {
1323 myNetBuilder->getTypeCont().insertEdgeType(edgeType.first, edgeType.second);
1324 for (int i = 0; i < (int)edgeType.second->getLaneTypes().size(); i++) {
1325 myNetBuilder->getTypeCont().insertLaneType(edgeType.first, i,
1326 edgeType.second->getLaneTypes().at(i)->speed,
1327 edgeType.second->getLaneTypes().at(i)->permissions,
1328 edgeType.second->getLaneTypes().at(i)->width,
1329 edgeType.second->getLaneTypes().at(i)->attrs);
1330 }
1331 }
1332 // write network
1333 NWFrame::writeNetwork(neteditOptions, *myNetBuilder);
1334 // reset output file
1335 sumoOptions.resetWritable();
1336 neteditOptions.resetDefault("output-file");
1337 // mark network as saved
1339}
1340
1341
1342void
1343GNENet::savePlain(const std::string& prefix) {
1344 auto& neteditOptions = OptionsCont::getOptions();
1345 // compute without volatile options
1346 computeAndUpdate(neteditOptions, false);
1347 NWWriter_XML::writeNetwork(neteditOptions, prefix, *myNetBuilder);
1348}
1349
1350
1351void
1352GNENet::saveJoined(const std::string& filename) {
1353 // compute without volatile options
1356}
1357
1358
1359void
1361 // set view net
1362 myViewNet = viewNet;
1363 // add default vTypes
1365 // update all edge geometries
1366 for (const auto& edge : myAttributeCarriers->getEdges()) {
1367 edge.second->updateGeometry();
1368 }
1369 // update view Net and recalculate edge boundaries)
1370 myViewNet->update();
1371 for (const auto& edge : myAttributeCarriers->getEdges()) {
1372 edge.second->updateCenteringBoundary(true);
1373 }
1374}
1375
1376
1377void
1379 // check if object must be inserted in RTREE
1380 if (AC->getTagProperty().isPlacedInRTree() && !AC->inGrid()) {
1382 AC->setInGrid(true);
1383 }
1384}
1385
1386
1387void
1389 // check if object must be inserted in RTREE
1390 if (AC->getTagProperty().isPlacedInRTree() && AC->inGrid()) {
1392 AC->setInGrid(false);
1393 }
1394}
1395
1396
1397void
1398GNENet::computeNetwork(GNEApplicationWindow* window, bool force, bool volatileOptions) {
1399 if (!myNeedRecompute) {
1400 if (force) {
1401 if (volatileOptions) {
1402 window->setStatusBarText(TL("Forced computing junctions with volatile options ..."));
1403 } else {
1404 window->setStatusBarText(TL("Forced computing junctions ..."));
1405 }
1406 } else {
1407 return;
1408 }
1409 } else {
1410 if (volatileOptions) {
1411 window->setStatusBarText(TL("Computing junctions with volatile options ..."));
1412 } else {
1413 window->setStatusBarText(TL("Computing junctions ..."));
1414 }
1415 }
1416 // start recomputing
1417 window->getApp()->beginWaitCursor();
1418 // save current number of lanes for every edge if recomputing is with volatile options
1419 if (volatileOptions) {
1420 for (const auto& edge : myAttributeCarriers->getEdges()) {
1421 myEdgesAndNumberOfLanes[edge.second->getID()] = (int)edge.second->getLanes().size();
1422 }
1423 }
1424 // compute and update
1425 auto& neteditOptions = OptionsCont::getOptions();
1426 computeAndUpdate(neteditOptions, volatileOptions);
1427 // load additionals if was recomputed with volatile options
1428 if (volatileOptions && OptionsCont::getOptions().getString("additional-files").size() > 0) {
1429 // Create additional handler
1430 GNEGeneralHandler generalHandler(this, OptionsCont::getOptions().getString("additional-files"),
1432 // Run parser
1433 if (!generalHandler.parse()) {
1434 WRITE_ERROR(TL("Loading of additional file failed: ") + OptionsCont::getOptions().getString("additional-files"));
1435 } else {
1436 WRITE_MESSAGE(TL("Loading of additional file successfully: ") + OptionsCont::getOptions().getString("additional-files"));
1437 }
1438 }
1439 // load demand elements if was recomputed with volatile options
1440 if (volatileOptions && OptionsCont::getOptions().getString("route-files").size() > 0) {
1441 // Create general handler
1442 GNEGeneralHandler generalHandler(this, OptionsCont::getOptions().getString("route-files"), false, true);
1443 // Run parser
1444 if (!generalHandler.parse()) {
1445 WRITE_ERROR(TL("Loading of route file failed: ") + OptionsCont::getOptions().getString("route-files"));
1446 } else {
1447 WRITE_MESSAGE(TL("Loading of route file successfully: ") + OptionsCont::getOptions().getString("route-files"));
1448 }
1449 }
1450 // load datas if was recomputed with volatile options
1451 if (volatileOptions && OptionsCont::getOptions().getString("data-files").size() > 0) {
1452 // Create data handler
1453 GNEDataHandler dataHandler(this, OptionsCont::getOptions().getString("data-files"), false, true);
1454 // Run parser
1455 if (!dataHandler.parse()) {
1456 WRITE_ERROR(TL("Loading of data file failed: ") + OptionsCont::getOptions().getString("data-files"));
1457 } else {
1458 WRITE_MESSAGE(TL("Loading of data file successfully: ") + OptionsCont::getOptions().getString("data-files"));
1459 }
1460 }
1461 // load meanDatas if was recomputed with volatile options
1462 if (volatileOptions && OptionsCont::getOptions().getString("meandata-files").size() > 0) {
1463 // Create meanData handler
1464 GNEGeneralHandler generalHandler(this, OptionsCont::getOptions().getString("meandata-files"), false, true);
1465 // Run parser
1466 if (!generalHandler.parse()) {
1467 WRITE_ERROR(TL("Loading of meandata file failed: ") + OptionsCont::getOptions().getString("meandata-files"));
1468 } else {
1469 WRITE_MESSAGE(TL("Loading of meandata file successfully: ") + OptionsCont::getOptions().getString("meandata-files"));
1470 }
1471 }
1472 // clear myEdgesAndNumberOfLanes after reload additionals
1474 // end recomputing
1475 window->getApp()->endWaitCursor();
1476 // update status bar
1477 window->setStatusBarText(TL("Finished computing junctions."));
1478}
1479
1480
1481void
1483 window->setStatusBarText(TL("Computing demand elements ..."));
1484 // if we aren't in Demand mode, update path calculator
1488 }
1489 // clear demand paths
1491 // iterate over all demand elements and compute
1492 for (const auto& demandElements : myAttributeCarriers->getDemandElements()) {
1493 for (const auto& demandElement : demandElements.second) {
1494 demandElement.second->computePathElement();
1495 }
1496 }
1497 window->setStatusBarText(TL("Finished computing demand elements."));
1498}
1499
1500
1501void
1503 window->setStatusBarText(TL("Computing data elements ..."));
1504 // iterate over all demand elements and compute
1505 for (const auto& genericDataTag : myAttributeCarriers->getGenericDatas()) {
1506 for (const auto& genericData : genericDataTag.second) {
1507 genericData.second->computePathElement();
1508 }
1509 }
1510 window->setStatusBarText(TL("Finished computing data elements."));
1511}
1512
1513
1514void
1516 // recompute tl-logics
1517 auto& neteditOptions = OptionsCont::getOptions();
1519 // iterate over traffic lights definitions. Make a copy because invalid
1520 // definitions will be removed (and would otherwise destroy the iterator)
1521 const std::set<NBTrafficLightDefinition*> tlsDefs = junction->getNBNode()->getControllingTLS();
1522 for (auto it : tlsDefs) {
1523 it->setParticipantsInformation();
1524 it->setTLControllingInformation();
1525 tllCont.computeSingleLogic(neteditOptions, it);
1526 }
1527
1528 // @todo compute connections etc...
1529}
1530
1531
1532void
1536
1537
1538bool
1540 return !myNeedRecompute;
1541}
1542
1543
1544FXApp*
1546 return myViewNet->getApp();
1547}
1548
1549
1552 return myNetBuilder;
1553}
1554
1555
1556bool
1558 const auto selectedJunctions = myAttributeCarriers->getSelectedJunctions();
1559 if (selectedJunctions.size() < 2) {
1560 return false;
1561 }
1562 EdgeVector allIncoming;
1563 EdgeVector allOutgoing;
1564 std::set<NBNode*, ComparatorIdLess> cluster;
1565 for (const auto& selectedJunction : selectedJunctions) {
1566 cluster.insert(selectedJunction->getNBNode());
1567 const EdgeVector& incoming = selectedJunction->getNBNode()->getIncomingEdges();
1568 allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end());
1569 const EdgeVector& outgoing = selectedJunction->getNBNode()->getOutgoingEdges();
1570 allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end());
1571 }
1572 // create new junction
1573 Position pos;
1574 Position oldPos;
1575 bool setTL = false;
1576 std::string id = "cluster";
1577 TrafficLightType type;
1579 myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type, nodeType);
1580 // save position
1581 oldPos = pos;
1582 // Check that there isn't another junction in the same position as Pos but doesn't belong to cluster
1583 for (const auto& junction : myAttributeCarriers->getJunctions()) {
1584 if ((junction.second->getPositionInView() == pos) && (cluster.find(junction.second->getNBNode()) == cluster.end())) {
1585 // show warning in gui testing debug mode
1586 WRITE_DEBUG("Opening FXMessageBox 'Join non-selected junction'");
1587 // Ask confirmation to user
1588 const std::string header = TL("Position of joined junction");
1589 const std::string bodyA = TL("There is another unselected junction in the same position of joined junction.");
1590 const std::string bodyB = TL("It will be joined with the other selected junctions. Continue?");
1591 const auto answer = FXMessageBox::question(getApp(), MBOX_YES_NO, header.c_str(), "%s", (bodyA + std::string("\n") + bodyB).c_str());
1592 if (answer != 1) { // 1:yes, 2:no, 4:esc
1593 // write warning if netedit is running in testing mode
1594 if (answer == 2) {
1595 WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'No'");
1596 } else if (answer == 4) {
1597 WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'ESC'");
1598 }
1599 return false;
1600 } else {
1601 // write warning if netedit is running in testing mode
1602 WRITE_DEBUG("Closed FXMessageBox 'Join non-selected junction' with 'Yes'");
1603 // select conflicted junction an join all again
1604 junction.second->setAttribute(GNE_ATTR_SELECTED, "true", undoList);
1605 return joinSelectedJunctions(undoList);
1606 }
1607 }
1608 }
1609 // use checkJunctionPosition to avoid conflicts with junction in the same position as others
1610 while (!checkJunctionPosition(pos)) {
1611 pos.setx(pos.x() + 0.1);
1612 pos.sety(pos.y() + 0.1);
1613 }
1614 // start with the join selected junctions
1615 undoList->begin(GUIIcon::JUNCTION, "Join selected " + toString(SUMO_TAG_JUNCTION) + "s");
1616 GNEJunction* joined = createJunction(pos, undoList);
1617 joined->setAttribute(SUMO_ATTR_TYPE, toString(nodeType), undoList); // i.e. rail crossing
1618 if (setTL) {
1619 joined->setAttribute(SUMO_ATTR_TLTYPE, toString(type), undoList);
1620 }
1622 // first remove all crossing of the involved junctions and edges
1623 // (otherwise edge removal will trigger discarding)
1624 std::vector<NBNode::Crossing> oldCrossings;
1625 for (const auto& selectedJunction : selectedJunctions) {
1626 const auto crossings = selectedJunction->getGNECrossings();
1627 for (auto crossing : crossings) {
1628 deleteCrossing(crossing, undoList);
1629 }
1630 }
1631 // preserve old connections
1632 for (const auto& selectedJunction : selectedJunctions) {
1633 selectedJunction->setLogicValid(false, undoList);
1634 }
1635 // remap edges
1636 for (const auto& incomingEdge : allIncoming) {
1637 if (std::find(allOutgoing.begin(), allOutgoing.end(), incomingEdge) == allOutgoing.end()) {
1638 GNEChange_Attribute::changeAttribute(myAttributeCarriers->getEdges().at(incomingEdge->getID()), SUMO_ATTR_TO, joined->getID(), undoList);
1639 }
1640 }
1641 EdgeSet edgesWithin;
1642 for (const auto& outgoingEdge : allOutgoing) {
1643 // delete edges within the cluster
1644 GNEEdge* edge = myAttributeCarriers->getEdges().at(outgoingEdge->getID());
1645 if (edge->getToJunction() == joined) {
1646 edgesWithin.insert(outgoingEdge);
1647 deleteEdge(edge, undoList, false);
1648 } else {
1649 GNEChange_Attribute::changeAttribute(myAttributeCarriers->getEdges().at(outgoingEdge->getID()), SUMO_ATTR_FROM, joined->getID(), undoList);
1650 }
1651 }
1652 // remap all crossing of the involved junctions and edges
1653 for (const auto& nbc : oldCrossings) {
1654 bool keep = true;
1655 for (NBEdge* e : nbc.edges) {
1656 if (edgesWithin.count(e) != 0) {
1657 keep = false;
1658 break;
1659 }
1660 };
1661 if (keep) {
1662 undoList->add(new GNEChange_Crossing(joined, nbc.edges, nbc.width,
1663 nbc.priority || joined->getNBNode()->isTLControlled(),
1664 nbc.customTLIndex, nbc.customTLIndex2, nbc.customShape,
1665 false, true), true);
1666 }
1667 }
1668 // delete original junctions
1669 for (const auto& selectedJunction : selectedJunctions) {
1670 deleteJunction(selectedJunction, undoList);
1671 }
1672 joined->setAttribute(SUMO_ATTR_ID, id, undoList);
1673
1674 // check if joined junction had to change their original position to avoid errors
1675 if (pos != oldPos) {
1676 joined->setAttribute(SUMO_ATTR_POSITION, toString(oldPos), undoList);
1677 }
1678 undoList->end();
1679 return true;
1680}
1681
1682
1683bool
1685 // obtain current net's crossings
1686 std::vector<GNECrossing*> myNetCrossings;
1687 for (const auto& junction : myAttributeCarriers->getJunctions()) {
1688 myNetCrossings.reserve(myNetCrossings.size() + junction.second->getGNECrossings().size());
1689 myNetCrossings.insert(myNetCrossings.end(), junction.second->getGNECrossings().begin(), junction.second->getGNECrossings().end());
1690 }
1691 // obtain invalid crossings
1692 std::vector<GNECrossing*> myInvalidCrossings;
1693 for (auto i = myNetCrossings.begin(); i != myNetCrossings.end(); i++) {
1694 if (!(*i)->getNBCrossing()->valid) {
1695 myInvalidCrossings.push_back(*i);
1696 }
1697 }
1698
1699 if (myInvalidCrossings.empty()) {
1700 // show warning in gui testing debug mode
1701 WRITE_DEBUG("Opening FXMessageBox 'No crossing to remove'");
1702 // open a dialog informing that there isn't crossing to remove
1703 const std::string header = TL("Clear crossings");
1704 const std::string body = TL("There are no invalid crossings to remove.");
1705 FXMessageBox::warning(getApp(), MBOX_OK, (header).c_str(), "%s", (body).c_str());
1706 // show warning in gui testing debug mode
1707 WRITE_DEBUG("Closed FXMessageBox 'No crossing to remove' with 'OK'");
1708 } else {
1709 std::string plural = myInvalidCrossings.size() == 1 ? ("") : ("s");
1710 // show warning in gui testing debug mode
1711 WRITE_DEBUG("Opening FXMessageBox 'clear crossings'");
1712 // Ask confirmation to user
1713 const std::string header = TL("Clear crossings");
1714 const std::string body = TL("Crossings will be cleared. Continue?");
1715 const auto answer = FXMessageBox::question(getApp(), MBOX_YES_NO, header.c_str(), "%s", body.c_str());
1716 // 1:yes, 2:no, 4:esc
1717 if (answer != 1) {
1718 // write warning if netedit is running in testing mode
1719 if (answer == 2) {
1720 WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'No'");
1721 } else if (answer == 4) {
1722 WRITE_DEBUG("Closed FXMessageBox 'clear crossings' with 'ESC'");
1723 }
1724 } else {
1725 undoList->begin(GUIIcon::MODEDELETE, TL("clear crossings"));
1726 for (auto i = myInvalidCrossings.begin(); i != myInvalidCrossings.end(); i++) {
1727 deleteCrossing((*i), undoList);
1728 }
1729 undoList->end();
1730 }
1731 }
1732 return 1;
1733}
1734
1735
1736void
1738 undoList->begin(GUIIcon::MODEDELETE, TL("clear junctions"));
1739 std::vector<GNEJunction*> toRemove;
1740 for (auto& junction : myAttributeCarriers->getJunctions()) {
1741 if (junction.second->getNBNode()->getEdges().size() == 0) {
1742 toRemove.push_back(junction.second);
1743 }
1744 }
1745 for (auto junction : toRemove) {
1746 deleteJunction(junction, undoList);
1747 }
1748 undoList->end();
1749}
1750
1751
1752void
1754 // first declare a vector to save all routes without children
1755 std::vector<GNEDemandElement*> routesWithoutChildren;
1756 routesWithoutChildren.reserve(myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE).size());
1757 // iterate over routes
1758 for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1759 if (route.second->getChildDemandElements().empty()) {
1760 routesWithoutChildren.push_back(route.second);
1761 }
1762 }
1763 // finally remove all routesWithoutChildren
1764 if (routesWithoutChildren.size() > 0) {
1765 // begin undo list
1766 undoList->begin(GUIIcon::MODEDELETE, TL("clear unused routes"));
1767 // iterate over routesWithoutChildren
1768 for (const auto& i : routesWithoutChildren) {
1769 // due route doesn't have children, simply call GNEChange_DemandElement
1770 undoList->add(new GNEChange_DemandElement(i, false), true);
1771 }
1772 // end undo list
1773 undoList->end();
1774 }
1775}
1776
1777
1778void
1780 // first declare a sorted set of sorted route's edges in string format
1781 std::set<std::pair<std::string, GNEDemandElement*> > mySortedRoutes;
1782 // iterate over routes and save it in mySortedRoutes (only if it doesn't have Stop Children)
1783 for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1784 // first check route has stops
1785 bool hasStops = false;
1786 for (const auto& stop : route.second->getChildDemandElements()) {
1787 if (stop->getTagProperty().isVehicleStop()) {
1788 hasStops = true;
1789 }
1790 }
1791 if (!hasStops) {
1792 mySortedRoutes.insert(std::make_pair(GNEAttributeCarrier::parseIDs(route.second->getParentEdges()), route.second));
1793 }
1794 }
1795 // now declare a matrix in which organize routes to be merged
1796 std::vector<std::vector<GNEDemandElement*> > routesToMerge;
1797 auto index = mySortedRoutes.begin();
1798 // iterate over mySortedRoutes
1799 for (auto i = mySortedRoutes.begin(); i != mySortedRoutes.end(); i++) {
1800 if (routesToMerge.empty()) {
1801 routesToMerge.push_back({i->second});
1802 } else {
1803 if (index->first == i->first) {
1804 routesToMerge.back().push_back(i->second);
1805 } else {
1806 routesToMerge.push_back({i->second});
1807 index = i;
1808 }
1809 }
1810 }
1811 // now check if there is routes to merge
1812 bool thereIsRoutesToMerge = false;
1813 for (const auto& i : routesToMerge) {
1814 if (i.size() > 1) {
1815 thereIsRoutesToMerge = true;
1816 }
1817 }
1818 // if exist
1819 if (thereIsRoutesToMerge) {
1820 // begin undo list
1821 undoList->begin(GUIIcon::ROUTE, TL("merge routes"));
1822 // iterate over route to edges
1823 for (const auto& routes : routesToMerge) {
1824 if (routes.size() > 1) {
1825 // iterate over duplicated routes
1826 for (int i = 1; i < (int)routes.size(); i++) {
1827 // move all vehicles of every duplicated route
1828 while (routes.at(i)->getChildDemandElements().size() > 0) {
1829 routes.at(i)->getChildDemandElements().front()->setAttribute(SUMO_ATTR_ROUTE, routes.at(0)->getID(), undoList);
1830 }
1831 // finally remove route
1832 undoList->add(new GNEChange_DemandElement(routes.at(i), false), true);
1833 }
1834 }
1835 }
1836 // end undo list
1837 undoList->end();
1838 }
1839}
1840
1841
1842void
1844 // declare personPlan-pos map
1845 std::map<GNEDemandElement*, std::string> personPlanMap;
1846 // iterate over persons
1847 for (const auto& persontag : {
1849 }) {
1850 for (const auto& person : myAttributeCarriers->getDemandElements().at(persontag)) {
1851 if (person.second->getChildDemandElements().size() > 0) {
1852 // get person plan
1853 GNEDemandElement* personPlan = person.second->getChildDemandElements().front();
1854 // iterate over all personPlans
1855 while (personPlan) {
1856 // check if personPlan is a stopPerson over edge
1857 if (personPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_EDGE) {
1858 // get previous person plan
1859 GNEDemandElement* previousPersonPlan = person.second->getPreviousChildDemandElement(personPlan);
1860 // check if arrivalPos of previous personPlan is different of endPos of stopPerson
1861 if (previousPersonPlan && previousPersonPlan->getTagProperty().hasAttribute(SUMO_ATTR_ARRIVALPOS) &&
1862 (previousPersonPlan->getAttribute(SUMO_ATTR_ARRIVALPOS) != personPlan->getAttribute(SUMO_ATTR_ENDPOS))) {
1863 personPlanMap[previousPersonPlan] = personPlan->getAttribute(SUMO_ATTR_ENDPOS);
1864 }
1865 }
1866 // go to next person plan
1867 personPlan = person.second->getNextChildDemandElement(personPlan);
1868 }
1869 }
1870 }
1871 }
1872 // continue if there is personPlanMap to adjust
1873 if (personPlanMap.size() > 0) {
1874 // begin undo list
1875 undoList->begin(GUIIcon::MODEPERSONPLAN, TL("adjust person plans"));
1876 // iterate over invalidDemandElements
1877 for (const auto& personPlan : personPlanMap) {
1878 // set arrivalPos attribute
1879 personPlan.first->setAttribute(SUMO_ATTR_ARRIVALPOS, personPlan.second, undoList);
1880 }
1881 // end undo list
1882 undoList->end();
1883 }
1884}
1885
1886
1887void
1889 // first declare a vector to save all invalid demand elements
1890 std::vector<GNEDemandElement*> invalidDemandElements;
1891 invalidDemandElements.reserve(myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE).size() +
1894 // iterate over routes
1895 for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
1896 if (route.second->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1897 invalidDemandElements.push_back(route.second);
1898 }
1899 }
1900 // iterate over flows
1901 for (const auto& flow : myAttributeCarriers->getDemandElements().at(SUMO_TAG_FLOW)) {
1902 if (flow.second->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1903 invalidDemandElements.push_back(flow.second);
1904 }
1905 }
1906 // iterate over trip
1907 for (const auto& trip : myAttributeCarriers->getDemandElements().at(SUMO_TAG_TRIP)) {
1908 if (trip.second->isDemandElementValid() != GNEDemandElement::Problem::OK) {
1909 invalidDemandElements.push_back(trip.second);
1910 }
1911 }
1912 // continue if there is invalidDemandElements to remove
1913 if (invalidDemandElements.size() > 0) {
1914 // begin undo list
1915 undoList->begin(GUIIcon::MODEDELETE, TL("remove invalid demand elements"));
1916 // iterate over invalidDemandElements
1917 for (const auto& invalidDemandElement : invalidDemandElements) {
1918 // simply call GNEChange_DemandElement
1919 undoList->add(new GNEChange_DemandElement(invalidDemandElement, false), true);
1920 }
1921 // end undo list
1922 undoList->end();
1923 }
1924}
1925
1926void
1928 if (junction->getNBNode()->checkIsRemovable()) {
1929 // start operation
1930 undoList->begin(junction, TL("replace junction by geometry"));
1931 // obtain Edges to join
1932 std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
1933 // clear connections of junction to replace
1934 clearJunctionConnections(junction, undoList);
1935 // iterate over NBEdges to join
1936 for (auto j : toJoin) {
1937 // obtain GNEEdges
1938 GNEEdge* begin = myAttributeCarriers->getEdges().at(j.first->getID());
1939 GNEEdge* continuation = myAttributeCarriers->getEdges().at(j.second->getID());
1940 // remove connections between the edges
1941 std::vector<NBEdge::Connection> connections = begin->getNBEdge()->getConnections();
1942 for (auto con : connections) {
1943 undoList->add(new GNEChange_Connection(begin, con, false, false), true);
1944 }
1945 // fix shape of replaced edge
1946 PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
1948 newShape.push_back(junction->getNBNode()->getPosition());
1949 } else {
1950 newShape.push_back(begin->getNBEdge()->getGeometry()[-1]);
1951 }
1952 if (continuation->getNBEdge()->hasDefaultGeometryEndpointAtNode(begin->getNBEdge()->getToNode())) {
1953 newShape.push_back_noDoublePos(junction->getNBNode()->getPosition());
1954 } else {
1955 newShape.push_back_noDoublePos(continuation->getNBEdge()->getGeometry()[0]);
1956 }
1957 // replace incoming edge
1958 replaceIncomingEdge(continuation, begin, undoList);
1959
1960 newShape.append(continuation->getNBEdge()->getInnerGeometry());
1961 begin->setAttribute(GNE_ATTR_SHAPE_END, continuation->getAttribute(GNE_ATTR_SHAPE_END), undoList);
1962 begin->setAttribute(SUMO_ATTR_ENDOFFSET, continuation->getAttribute(SUMO_ATTR_ENDOFFSET), undoList);
1963 begin->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
1964 begin->getNBEdge()->resetNodeBorder(begin->getNBEdge()->getToNode());
1965 // fix loaded lengths
1966 if (begin->getNBEdge()->hasLoadedLength() || continuation->getNBEdge()->hasLoadedLength()) {
1967 begin->setAttribute(SUMO_ATTR_LENGTH, toString(begin->getNBEdge()->getLoadedLength() + continuation->getNBEdge()->getLoadedLength()), undoList);
1968 }
1969 }
1970 //delete replaced junction
1971 deleteJunction(junction, undoList);
1972 // finish operation
1973 undoList->end();
1974 } else {
1975 throw ProcessError(TL("Junction isn't removable"));
1976 }
1977}
1978
1979
1980void
1981GNENet::splitJunction(GNEJunction* junction, bool reconnect, GNEUndoList* undoList) {
1982 std::vector<std::pair<Position, std::string> > endpoints = junction->getNBNode()->getEndPoints();
1983 if (endpoints.size() < 2) {
1984 return;
1985 }
1986 // start operation
1987 undoList->begin(junction, TL("split junction"));
1988 // record connections
1989 std::map<GNEEdge*, std::vector<NBEdge::Connection>> straightConnections;
1990 for (GNEEdge* e : junction->getGNEIncomingEdges()) {
1991 for (const auto& c : e->getNBEdge()->getConnections()) {
1992 if (c.fromLane >= 0 && junction->getNBNode()->getDirection(e->getNBEdge(), c.toEdge) == LinkDirection::STRAIGHT) {
1993 straightConnections[e].push_back(c);
1994 }
1995 };
1996 }
1997 //std::cout << "split junction at endpoints:\n";
1998
1999 junction->setLogicValid(false, undoList);
2000 for (const auto& pair : endpoints) {
2001 const Position& pos = pair.first;
2002 const std::string& origID = pair.second;
2003 GNEJunction* newJunction = createJunction(pos, undoList);
2004 std::string newID = origID != "" ? origID : newJunction->getID();
2005 // make a copy because the original vectors are modified during iteration
2006 const std::vector<GNEEdge*> incoming = junction->getGNEIncomingEdges();
2007 const std::vector<GNEEdge*> outgoing = junction->getGNEOutgoingEdges();
2008 //std::cout << " checkEndpoint " << pair.first << " " << pair.second << " newID=" << newID << "\n";
2009 for (GNEEdge* e : incoming) {
2010 //std::cout << " incoming " << e->getID() << " pos=" << pos << " origTo=" << e->getNBEdge()->getParameter("origTo") << " newID=" << newID << "\n";
2011 if (e->getNBEdge()->getGeometry().back().almostSame(pos) || e->getNBEdge()->getParameter("origTo") == newID) {
2012 //std::cout << " match\n";
2013 GNEChange_Attribute::changeAttribute(e, SUMO_ATTR_TO, newJunction->getID(), undoList);
2014 }
2015 }
2016 for (GNEEdge* e : outgoing) {
2017 //std::cout << " outgoing " << e->getID() << " pos=" << pos << " origFrom=" << e->getNBEdge()->getParameter("origFrom") << " newID=" << newID << "\n";
2018 if (e->getNBEdge()->getGeometry().front().almostSame(pos) || e->getNBEdge()->getParameter("origFrom") == newID) {
2019 //std::cout << " match\n";
2020 GNEChange_Attribute::changeAttribute(e, SUMO_ATTR_FROM, newJunction->getID(), undoList);
2021 }
2022 }
2023 if (newID != newJunction->getID()) {
2024 if (newJunction->isValid(SUMO_ATTR_ID, newID)) {
2025 GNEChange_Attribute::changeAttribute(newJunction, SUMO_ATTR_ID, newID, undoList);
2026 } else {
2027 WRITE_WARNINGF(TL("Could not rename split node to '%'"), newID);
2028 }
2029 }
2030 }
2031 // recreate edges from straightConnections
2032 if (reconnect) {
2033 for (const auto& item : straightConnections) {
2034 GNEEdge* in = item.first;
2035 std::map<NBEdge*, GNEEdge*> newEdges;
2036 for (auto& c : item.second) {
2037 GNEEdge* out = myAttributeCarriers->retrieveEdge(c.toEdge->getID());
2038 GNEEdge* newEdge = nullptr;
2039 if (in->getToJunction() == out->getFromJunction()) {
2040 continue;
2041 }
2042 if (newEdges.count(c.toEdge) == 0) {
2043 newEdge = createEdge(in->getToJunction(), out->getFromJunction(), in, undoList);
2044 newEdges[c.toEdge] = newEdge;
2045 newEdge->setAttribute(SUMO_ATTR_NUMLANES, "1", undoList);
2046 } else {
2047 newEdge = newEdges[c.toEdge];
2048 duplicateLane(newEdge->getLanes().back(), undoList, true);
2049 }
2050 // copy permissions
2051 newEdge->getLanes().back()->setAttribute(SUMO_ATTR_ALLOW,
2052 in->getLanes()[c.fromLane]-> getAttribute(SUMO_ATTR_ALLOW), undoList);
2053 }
2054 }
2055 }
2056
2057 deleteJunction(junction, undoList);
2058 // finish operation
2059 undoList->end();
2060}
2061
2062
2063
2064void
2066 undoList->begin(GUIIcon::MODEDELETE, TL("clear junction connections"));
2067 std::vector<GNEConnection*> connections = junction->getGNEConnections();
2068 // Iterate over all connections and clear it
2069 for (auto i : connections) {
2070 deleteConnection(i, undoList);
2071 }
2072 undoList->end();
2073}
2074
2075
2076void
2078 undoList->begin(junction, TL("reset junction connections"));
2079 // first clear connections
2080 clearJunctionConnections(junction, undoList);
2081 // invalidate logic to create new connections in the next recomputing
2082 junction->setLogicValid(false, undoList);
2083 undoList->end();
2084}
2085
2086
2087void
2089 undoList->begin(GUIIcon::MODEDELETE, TL("clear additional elements"));
2090 // clear additionals
2091 for (const auto& additionalMap : myAttributeCarriers->getAdditionals()) {
2092 while (additionalMap.second.size() > 0) {
2093 deleteAdditional(additionalMap.second.begin()->second, undoList);
2094 }
2095 }
2096 undoList->end();
2097}
2098
2099
2100void
2102 undoList->begin(GUIIcon::MODEDELETE, TL("clear demand elements"));
2103 // clear demand elements
2104 for (const auto& demandElementsMap : myAttributeCarriers->getDemandElements()) {
2105 while (demandElementsMap.second.size() > 0) {
2106 deleteDemandElement(demandElementsMap.second.begin()->second, undoList);
2107 }
2108 }
2109 undoList->end();
2110}
2111
2112
2113void
2115 undoList->begin(GUIIcon::MODEDELETE, TL("clear data elements"));
2116 // clear data sets
2117 for (const auto& dataSet : myAttributeCarriers->getDataSets()) {
2118 deleteDataSet(dataSet.second, undoList);
2119 }
2120 undoList->end();
2121}
2122
2123
2124void
2126 undoList->begin(GUIIcon::MODEDELETE, TL("clear meanData elements"));
2127 // clear meanDatas
2128 for (const auto& meanDataMap : myAttributeCarriers->getMeanDatas()) {
2129 while (meanDataMap.second.size() > 0) {
2130 deleteMeanData(meanDataMap.second.begin()->second, undoList);
2131 }
2132 }
2133 undoList->end();
2134}
2135
2136
2137void
2138GNENet::changeEdgeEndpoints(GNEEdge* edge, const std::string& newSource, const std::string& newDest) {
2141 edge->getNBEdge()->reinitNodes(from, to);
2143}
2144
2145
2148 return myViewNet;
2149}
2150
2151
2156
2157
2162
2163
2164void
2168
2169
2170void
2172 myExplicitTurnarounds.erase(id);
2173}
2174
2175
2176void
2178 // obtain invalid additionals depending of number of their parent lanes
2179 std::vector<GNEAdditional*> invalidSingleLaneAdditionals;
2180 std::vector<GNEAdditional*> invalidMultiLaneAdditionals;
2181 // iterate over additionals and obtain invalids
2182 for (const auto& additionalPair : myAttributeCarriers->getAdditionals()) {
2183 for (const auto& addditional : additionalPair.second) {
2184 // check if has to be fixed
2185 if (addditional.second->getTagProperty().hasAttribute(SUMO_ATTR_LANE) && !addditional.second->isAdditionalValid()) {
2186 invalidSingleLaneAdditionals.push_back(addditional.second);
2187 } else if (addditional.second->getTagProperty().hasAttribute(SUMO_ATTR_LANES) && !addditional.second->isAdditionalValid()) {
2188 invalidMultiLaneAdditionals.push_back(addditional.second);
2189 }
2190 }
2191 }
2192 // if there are invalid StoppingPlaces or detectors, open GNEFixAdditionalElements
2193 if (invalidSingleLaneAdditionals.size() > 0 || invalidMultiLaneAdditionals.size() > 0) {
2194 // 0 -> Canceled Saving, with or without selecting invalid stopping places and E2
2195 // 1 -> Invalid stoppingPlaces and E2 fixed, friendlyPos enabled, or saved with invalid positions
2196 GNEFixAdditionalElements fixAdditionalElementsDialog(myViewNet, invalidSingleLaneAdditionals, invalidMultiLaneAdditionals);
2197 if (fixAdditionalElementsDialog.execute() == 0) {
2198 // show debug information
2199 WRITE_DEBUG("Additionals saving aborted");
2200 } else {
2202 // show debug information
2203 WRITE_DEBUG("Additionals saved after dialog");
2204 }
2205 // set focus again in net
2206 myViewNet->setFocus();
2207 } else {
2209 // show debug information
2210 WRITE_DEBUG("Additionals saved");
2211 }
2212}
2213
2214
2215void
2216GNENet::saveJuPedSimElements(const std::string& file) {
2217 OutputDevice& device = OutputDevice::getDevice(file);
2218 // open header
2219 device.writeXMLHeader("additional", "additional_file.xsd", EMPTY_HEADER, false);
2220 // juPedSim elements
2221 writeJuPedSimComment(device);
2224 // close device
2225 device.close();
2226}
2227
2228
2229void
2231 // first recompute demand elements
2233 // obtain invalid demandElements depending of number of their parent lanes
2234 std::vector<GNEDemandElement*> invalidSingleLaneDemandElements;
2235 // iterate over demandElements and obtain invalids
2236 for (const auto& demandElementSet : myAttributeCarriers->getDemandElements()) {
2237 for (const auto& demandElement : demandElementSet.second) {
2238 // compute before check if demand element is valid
2239 demandElement.second->computePathElement();
2240 // check if has to be fixed
2241 if (demandElement.second->isDemandElementValid() != GNEDemandElement::Problem::OK) {
2242 invalidSingleLaneDemandElements.push_back(demandElement.second);
2243 }
2244 }
2245 }
2246 // if there are invalid demand elements, open GNEFixDemandElements
2247 if (invalidSingleLaneDemandElements.size() > 0) {
2248 // 0 -> Canceled Saving, with or without selecting invalid demand elements
2249 // 1 -> Invalid demand elements fixed, friendlyPos enabled, or saved with invalid positions
2250 GNEFixDemandElements fixDemandElementsDialog(myViewNet, invalidSingleLaneDemandElements);
2251 if (fixDemandElementsDialog.execute() == 0) {
2252 // show debug information
2253 WRITE_DEBUG("demand elements saving aborted");
2254 } else {
2256 // show debug information
2257 WRITE_DEBUG("demand elements saved after dialog");
2258 }
2259 // set focus again in net
2260 myViewNet->setFocus();
2261 } else {
2263 // show debug information
2264 WRITE_DEBUG("demand elements saved");
2265 }
2266}
2267
2268
2269void
2271 // first recompute data sets
2273 // save data elements
2275 // show debug information
2276 WRITE_DEBUG("data sets saved");
2277}
2278
2279
2280double
2282 double minimumBegin = 0;
2283 // update with first minimum (if exist)
2284 if (myAttributeCarriers->getDataIntervals().size() > 0) {
2285 minimumBegin = myAttributeCarriers->getDataIntervals().begin()->second->getAttributeDouble(SUMO_ATTR_BEGIN);
2286 }
2287 // iterate over interval
2288 for (const auto& interval : myAttributeCarriers->getDataIntervals()) {
2289 if (interval.second->getAttributeDouble(SUMO_ATTR_BEGIN) < minimumBegin) {
2290 minimumBegin = interval.second->getAttributeDouble(SUMO_ATTR_BEGIN);
2291 }
2292 }
2293 return minimumBegin;
2294}
2295
2296
2297double
2299 double maximumEnd = 0;
2300 // update with first maximum (if exist)
2301 if (myAttributeCarriers->getDataIntervals().size() > 0) {
2302 maximumEnd = myAttributeCarriers->getDataIntervals().begin()->second->getAttributeDouble(SUMO_ATTR_END);
2303 }
2304 // iterate over intervals
2305 for (const auto& interval : myAttributeCarriers->getDataIntervals()) {
2306 if (interval.second->getAttributeDouble(SUMO_ATTR_END) > maximumEnd) {
2307 maximumEnd = interval.second->getAttributeDouble(SUMO_ATTR_END);
2308 }
2309 }
2310 return maximumEnd;
2311}
2312
2313
2314void
2317 // show debug information
2318 WRITE_DEBUG("MeanDatas saved");
2319}
2320
2321
2322void
2324 OutputDevice& device = OutputDevice::getDevice(OptionsCont::getOptions().getString("additional-files"));
2325 // open header
2326 device.writeXMLHeader("additional", "additional_file.xsd", EMPTY_HEADER, false);
2327 // write vTypes with additional childrens (due calibrators)
2328 writeVTypeComment(device, true);
2329 writeVTypeDistributions(device, true);
2330 writeVTypes(device, true);
2331 // write routes with additional children (due route prob reroutes)
2332 writeRouteComment(device, true);
2333 writeRouteDistributions(device, true);
2334 writeRoutes(device, true);
2335 // routeProbes
2336 writeRouteProbeComment(device);
2338 // calibrator
2339 writeCalibratorComment(device);
2341 // stoppingPlaces
2348 // detectors
2349 writeDetectorComment(device);
2354 // Other additionals
2359 // shapes
2360 writeShapesComment(device);
2363 // TAZs
2364 writeTAZComment(device);
2366 // Wire element
2367 writeWireComment(device);
2371 // juPedSim elements
2372 writeJuPedSimComment(device);
2375 // close device
2376 device.close();
2377 // mark additionals as saved
2379}
2380
2381
2382void
2384 OutputDevice& device = OutputDevice::getDevice(OptionsCont::getOptions().getString("route-files"));
2385 // open header
2386 device.writeXMLHeader("routes", "routes_file.xsd", EMPTY_HEADER, false);
2387 // first write all vTypeDistributions (and their vTypes)
2388 writeVTypeComment(device, false);
2389 writeVTypes(device, false);
2390 writeVTypeDistributions(device, false);
2391 // now write all routes (and their associated stops), except routes with additional children (due routeProbReroutes)
2392 writeRouteComment(device, false);
2393 writeRoutes(device, false);
2394 writeRouteDistributions(device, false);
2395 // sort vehicles/persons by depart
2396 std::map<double, std::map<std::pair<SumoXMLTag, std::string>, GNEDemandElement*> > vehiclesSortedByDepart;
2397 for (const auto& demandElementTag : myAttributeCarriers->getDemandElements()) {
2398 for (const auto& demandElement : demandElementTag.second) {
2399 if (demandElement.second->getTagProperty().isVehicle() || demandElement.second->getTagProperty().isPerson() || demandElement.second->getTagProperty().isContainer()) {
2400 vehiclesSortedByDepart[demandElement.second->getAttributeDouble(SUMO_ATTR_DEPART)][std::make_pair(demandElement.second->getTagProperty().getTag(), demandElement.second->getID())] = demandElement.second;
2401 }
2402 }
2403 }
2404 // finally write all vehicles, persons and containers sorted by depart time (and their associated stops, personPlans, etc.)
2405 if (vehiclesSortedByDepart.size() > 0) {
2406 device << (" <!-- Vehicles, persons and containers (sorted by depart) -->\n");
2407 for (const auto& vehicleTag : vehiclesSortedByDepart) {
2408 for (const auto& vehicle : vehicleTag.second) {
2409 vehicle.second->writeDemandElement(device);
2410 }
2411 }
2412 }
2413 // close device
2414 device.close();
2415 // mark demand elements as saved
2417}
2418
2419
2420void
2422 OutputDevice& device = OutputDevice::getDevice(OptionsCont::getOptions().getString("data-files"));
2423 device.writeXMLHeader("data", "datamode_file.xsd", EMPTY_HEADER, false);
2424 // write all data sets
2425 for (const auto& dataSet : myAttributeCarriers->getDataSets()) {
2426 dataSet.second->writeDataSet(device);
2427 }
2428 // close device
2429 device.close();
2430 // mark data element as saved
2432}
2433
2434
2435void
2437 OutputDevice& device = OutputDevice::getDevice(OptionsCont::getOptions().getString("meandata-files"));
2438 // open header
2439 device.writeXMLHeader("additional", "additional_file.xsd", EMPTY_HEADER, false);
2440 // MeanDataEdges
2443 // MeanDataLanes
2446 // close device
2447 device.close();
2448 // mark mean datas as saved
2450}
2451
2452
2453void
2454GNENet::writeAdditionalByType(OutputDevice& device, const std::vector<SumoXMLTag> tags) const {
2455 std::map<std::string, GNEAdditional*> sortedAdditionals;
2456 for (const auto& tag : tags) {
2457 for (const auto& additional : myAttributeCarriers->getAdditionals().at(tag)) {
2458 if (sortedAdditionals.count(additional.second->getID()) == 0) {
2459 sortedAdditionals[additional.second->getID()] = additional.second;
2460 } else {
2461 throw ProcessError(TL("Duplicated ID"));
2462 }
2463 }
2464 }
2465 for (const auto& additional : sortedAdditionals) {
2466 additional.second->writeAdditional(device);
2467 }
2468}
2469
2470
2471void
2473 std::map<std::string, GNEDemandElement*> sortedDemandElements;
2474 for (const auto& demandElement : myAttributeCarriers->getDemandElements().at(tag)) {
2475 sortedDemandElements[demandElement.second->getID()] = demandElement.second;
2476 }
2477 for (const auto& demandElement : sortedDemandElements) {
2478 demandElement.second->writeDemandElement(device);
2479 }
2480}
2481
2482
2483void
2484GNENet::writeRouteDistributions(OutputDevice& device, const bool additionalFile) const {
2485 std::map<std::string, GNEDemandElement*> sortedElements;
2486 // first write route Distributions
2487 for (const auto& routeDistribution : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE_DISTRIBUTION)) {
2488 // get number of additional children
2489 const auto numChildren = routeDistribution.second->getAttributeDouble(GNE_ATTR_ADDITIONALCHILDREN);
2490 if ((additionalFile && (numChildren != 0)) || (!additionalFile && (numChildren == 0))) {
2491 sortedElements[routeDistribution.second->getID()] = routeDistribution.second;
2492 }
2493 }
2494 for (const auto& element : sortedElements) {
2495 element.second->writeDemandElement(device);
2496 }
2497 sortedElements.clear();
2498}
2499
2500
2501void
2502GNENet::writeRoutes(OutputDevice& device, const bool additionalFile) const {
2503 std::map<std::string, GNEDemandElement*> sortedRoutes;
2504 for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
2505 if ((additionalFile && (route.second->getChildAdditionals().size() > 0)) ||
2506 (!additionalFile && (route.second->getChildAdditionals().size() == 0))) {
2507 sortedRoutes[route.second->getID()] = route.second;
2508 }
2509 }
2510 for (const auto& route : sortedRoutes) {
2511 route.second->writeDemandElement(device);
2512 }
2513}
2514
2515
2516void
2517GNENet::writeVTypeDistributions(OutputDevice& device, const bool additionalFile) const {
2518 std::map<std::string, GNEDemandElement*> sortedElements;
2519 // first write vType Distributions
2520 for (const auto& vTypeDistribution : myAttributeCarriers->getDemandElements().at(SUMO_TAG_VTYPE_DISTRIBUTION)) {
2521 // get number of additional children
2522 const auto numChildren = vTypeDistribution.second->getAttributeDouble(GNE_ATTR_ADDITIONALCHILDREN);
2523 if ((additionalFile && (numChildren != 0)) || (!additionalFile && (numChildren == 0))) {
2524 sortedElements[vTypeDistribution.second->getID()] = vTypeDistribution.second;
2525 }
2526 }
2527 for (const auto& element : sortedElements) {
2528 element.second->writeDemandElement(device);
2529 }
2530 sortedElements.clear();
2531}
2532
2533
2534void
2535GNENet::writeVTypes(OutputDevice& device, const bool additionalFile) const {
2536 std::map<std::string, GNEDemandElement*> sortedElements;
2537 // write vTypes
2538 for (const auto& vType : myAttributeCarriers->getDemandElements().at(SUMO_TAG_VTYPE)) {
2539 // get number of additional children
2540 const auto numChildren = vType.second->getChildAdditionals().size();
2541 if ((additionalFile && (numChildren != 0)) || (!additionalFile && (numChildren == 0))) {
2542 sortedElements[vType.second->getID()] = vType.second;
2543 }
2544 }
2545 for (const auto& element : sortedElements) {
2546 element.second->writeDemandElement(device);
2547 }
2548}
2549
2550
2551void
2553 std::map<std::string, GNEMeanData*> sortedMeanDatas;
2554 for (const auto& meanData : myAttributeCarriers->getMeanDatas().at(tag)) {
2555 if (sortedMeanDatas.count(meanData.second->getID()) == 0) {
2556 sortedMeanDatas[meanData.second->getID()] = meanData.second;
2557 } else {
2558 throw ProcessError(TL("Duplicated ID"));
2559 }
2560 }
2561 for (const auto& additional : sortedMeanDatas) {
2562 additional.second->writeMeanData(device);
2563 }
2564}
2565
2566bool
2567GNENet::writeVTypeComment(OutputDevice& device, const bool additionalFile) const {
2568 // vTypes
2569 for (const auto& vType : myAttributeCarriers->getDemandElements().at(SUMO_TAG_VTYPE)) {
2570 // special case for default vTypes
2571 const bool defaultVType = GNEAttributeCarrier::parse<bool>(vType.second->getAttribute(GNE_ATTR_DEFAULT_VTYPE));
2572 const bool defaultVTypeModified = GNEAttributeCarrier::parse<bool>(vType.second->getAttribute(GNE_ATTR_DEFAULT_VTYPE_MODIFIED));
2573 // only write default vType modified
2574 if ((vType.second->getParentDemandElements().size() == 0) && (!defaultVType || (defaultVType && defaultVTypeModified))) {
2575 if (additionalFile && (vType.second->getChildAdditionals().size() != 0)) {
2576 device << (" <!-- VTypes (used in calibratorFlows) -->\n");
2577 return true;
2578 } else if (!additionalFile && (vType.second->getChildAdditionals().size() == 0)) {
2579 device << (" <!-- VTypes -->\n");
2580 return true;
2581 }
2582 }
2583 }
2584 return false;
2585}
2586
2587
2588bool
2589GNENet::writeRouteComment(OutputDevice& device, const bool additionalFile) const {
2590 for (const auto& route : myAttributeCarriers->getDemandElements().at(SUMO_TAG_ROUTE)) {
2591 if (additionalFile && (route.second->getChildAdditionals().size() != 0)) {
2592 device << (" <!-- Routes (used in RouteProbReroutes and calibratorFlows) -->\n");
2593 return true;
2594 } else if (!additionalFile && (route.second->getChildAdditionals().size() == 0)) {
2595 device << (" <!-- Routes -->\n");
2596 return true;
2597 }
2598 }
2599 return false;
2600}
2601
2602
2603bool
2606 device << (" <!-- RouteProbes -->\n");
2607 return true;
2608 }
2609 return false;
2610}
2611
2612
2613bool
2615 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2616 if (GNEAttributeCarrier::getTagProperty(additionals.first).isCalibrator() && (additionals.second.size() > 0)) {
2617 device << (" <!-- Calibrators -->\n");
2618 return true;
2619 }
2620 }
2621 return false;
2622}
2623
2624
2625bool
2627 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2628 if (GNEAttributeCarrier::getTagProperty(additionals.first).isStoppingPlace() && (additionals.second.size() > 0)) {
2629 device << (" <!-- StoppingPlaces -->\n");
2630 return true;
2631 }
2632 }
2633 return false;
2634}
2635
2636
2637bool
2639 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2640 if (GNEAttributeCarrier::getTagProperty(additionals.first).isDetector() && (additionals.second.size() > 0)) {
2641 device << (" <!-- Detectors -->\n");
2642 return true;
2643 }
2644 }
2645 return false;
2646}
2647
2648
2649bool
2651 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2654 !GNEAttributeCarrier::getTagProperty(additionals.first).isDetector() &&
2655 !GNEAttributeCarrier::getTagProperty(additionals.first).isCalibrator() &&
2656 (additionals.first != SUMO_TAG_ROUTEPROBE) && (additionals.first != SUMO_TAG_ACCESS) &&
2657 (additionals.first != SUMO_TAG_PARKING_SPACE) && (additionals.second.size() > 0)) {
2658 device << (" <!-- Other additionals -->\n");
2659 return true;
2660 }
2661 }
2662 return false;
2663}
2664
2665
2666bool
2668 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2669 if (GNEAttributeCarrier::getTagProperty(additionals.first).isShapeElement() &&
2671 (additionals.second.size() > 0)) {
2672 device << (" <!-- Shapes -->\n");
2673 return true;
2674 }
2675 }
2676 return false;
2677}
2678
2679
2680bool
2682 for (const auto& additionals : myAttributeCarriers->getAdditionals()) {
2683 if (GNEAttributeCarrier::getTagProperty(additionals.first).isJuPedSimElement() && (additionals.second.size() > 0)) {
2684 device << (" <!-- JuPedSim elements -->\n");
2685 return true;
2686 }
2687 }
2688 return false;
2689}
2690
2691
2692bool
2694 if (myAttributeCarriers->getAdditionals().at(SUMO_TAG_TAZ).size() > 0) {
2695 device << (" <!-- TAZs -->\n");
2696 return true;
2697 }
2698 return false;
2699}
2700
2701
2702bool
2705 device << (" <!-- Wires -->\n");
2706 return true;
2707 }
2708 return false;
2709}
2710
2711
2712bool
2715 device << (" <!-- MeanDataEdges -->\n");
2716 return true;
2717 }
2718 return false;
2719}
2720
2721
2722bool
2725 device << (" <!-- MeanDataLanes -->\n");
2726 return true;
2727 }
2728 return false;
2729}
2730
2731
2732void
2733GNENet::saveTLSPrograms(const std::string& filename) {
2734 // open output device
2735 OutputDevice& device = OutputDevice::getDevice(filename);
2736 device.openTag("additionals");
2737 // write traffic lights using NWWriter
2739 device.close();
2740 // change save status
2742 // show debug information
2743 WRITE_DEBUG("TLSPrograms saved");
2744}
2745
2746
2747int
2749 return -1;
2750}
2751
2752
2753void
2754GNENet::saveEdgeTypes(const std::string& filename) {
2755 // first clear typeContainer
2757 // now update typeContainer with edgeTypes
2758 for (const auto& edgeType : myAttributeCarriers->getEdgeTypes()) {
2759 myNetBuilder->getTypeCont().insertEdgeType(edgeType.first, edgeType.second);
2760 for (int i = 0; i < (int)edgeType.second->getLaneTypes().size(); i++) {
2761 myNetBuilder->getTypeCont().insertLaneType(edgeType.first, i,
2762 edgeType.second->getLaneTypes().at(i)->speed,
2763 edgeType.second->getLaneTypes().at(i)->permissions,
2764 edgeType.second->getLaneTypes().at(i)->width,
2765 edgeType.second->getLaneTypes().at(i)->attrs);
2766 }
2767 }
2768 // open device
2769 OutputDevice& device = OutputDevice::getDevice(filename);
2770 // open tag
2771 device.openTag(SUMO_TAG_TYPE);
2772 // write edge types
2774 // close tag
2775 device.closeTag();
2776 // close device
2777 device.close();
2778}
2779
2780
2781void
2785
2786
2787void
2791
2792
2793bool
2797
2798
2799void
2801 myUpdateDataEnabled = true;
2802 // update data elements
2803 for (const auto& dataInterval : myAttributeCarriers->getDataIntervals()) {
2804 dataInterval.second->updateGenericDataIDs();
2805 dataInterval.second->updateAttributeColors();
2806 }
2807}
2808
2809
2810void
2814
2815
2816bool
2820
2821// ===========================================================================
2822// private
2823// ===========================================================================
2824
2825void
2827 // init edge types
2828 for (const auto& edgeType : myNetBuilder->getTypeCont()) {
2829 // register edge type
2830 myAttributeCarriers->registerEdgeType(new GNEEdgeType(this, edgeType.first, edgeType.second));
2831 }
2832 // init junctions (by default Crossing and walking areas aren't created)
2833 for (const auto& nodeName : myNetBuilder->getNodeCont().getAllNames()) {
2834 // create and register junction
2836 }
2837 // init edges
2838 for (const auto& edgeName : myNetBuilder->getEdgeCont().getAllNames()) {
2839 // create edge using NBEdge
2840 GNEEdge* edge = new GNEEdge(this, myNetBuilder->getEdgeCont().retrieve(edgeName), false, true);
2841 // register edge
2843 // add manually child references due initJunctionsAndEdges doesn't use undo-redo
2844 edge->getFromJunction()->addChildElement(edge);
2845 edge->getToJunction()->addChildElement(edge);
2846 // check grid
2847 if (myGrid.getWidth() > 10e16 || myGrid.getHeight() > 10e16) {
2848 throw ProcessError(TL("Network size exceeds 1 Lightyear. Please reconsider your inputs.") + std::string("\n"));
2849 }
2850 }
2851 // make sure myGrid is initialized even for an empty net. This ensure that the network starts with a zoom of 100
2852 if (myAttributeCarriers->getEdges().size() == 0) {
2853 myGrid.add(Boundary(-50, -50, 50, 50));
2854 }
2855 // recalculate all lane2lane connections
2856 for (const auto& edge : myAttributeCarriers->getEdges()) {
2857 for (const auto& lane : edge.second->getLanes()) {
2858 lane->updateGeometry();
2859 }
2860 }
2861 // sort nodes edges so that arrows can be drawn correctly
2863}
2864
2865
2866void
2868 for (const auto& edge : myAttributeCarriers->getEdges()) {
2869 // remake connections
2870 edge.second->remakeGNEConnections();
2871 // update geometry of connections
2872 for (const auto& connection : edge.second->getGNEConnections()) {
2873 connection->updateGeometry();
2874 }
2875 }
2876}
2877
2878
2879void
2880GNENet::computeAndUpdate(OptionsCont& neteditOptions, bool volatileOptions) {
2881 // make sure we only add turn arounds to edges which currently exist within the network
2882 std::set<std::string> liveExplicitTurnarounds;
2883 for (const auto& explicitTurnarounds : myExplicitTurnarounds) {
2884 if (myAttributeCarriers->getEdges().count(explicitTurnarounds) > 0) {
2885 liveExplicitTurnarounds.insert(explicitTurnarounds);
2886 }
2887 }
2888 // removes all junctions of grid
2889 WRITE_GLDEBUG("Removing junctions during recomputing");
2890 for (const auto& junction : myAttributeCarriers->getJunctions()) {
2891 removeGLObjectFromGrid(junction.second);
2892 }
2893 // remove all edges from grid
2894 WRITE_GLDEBUG("Removing edges during recomputing");
2895 for (const auto& edge : myAttributeCarriers->getEdges()) {
2896 removeGLObjectFromGrid(edge.second);
2897 }
2898 // compute using NetBuilder
2899 myNetBuilder->compute(neteditOptions, liveExplicitTurnarounds, volatileOptions);
2900 // remap ids if necessary
2901 if (neteditOptions.getBool("numerical-ids") || neteditOptions.isSet("reserved-ids")) {
2903 }
2904 // update rtree if necessary
2905 if (!neteditOptions.getBool("offset.disable-normalization")) {
2906 for (const auto& edge : myAttributeCarriers->getEdges()) {
2907 // refresh edge geometry
2908 edge.second->updateGeometry();
2909 }
2910 }
2911 // Clear current inspected ACs in inspectorFrame if a previous net was loaded
2912 if (myViewNet != nullptr) {
2914 }
2915 // Reset Grid
2916 myGrid.reset();
2918 // if volatile options are true
2919 if (volatileOptions) {
2920 // check that net exist
2921 if (myViewNet == nullptr) {
2922 throw ProcessError("ViewNet doesn't exist");
2923 }
2924 // disable update geometry before clear undo list
2926 // destroy Popup
2928 // clear undo list (This will be remove additionals and shapes)
2930 // clear all elements (it will also removed from grid)
2935 // enable update geometry again
2937 // Write GL debug information
2938 WRITE_GLDEBUG("initJunctionsAndEdges function called in computeAndUpdate(...) due recomputing with volatile options");
2939 // init again junction an edges (Additionals and shapes will be loaded after the end of this function)
2941 // init default vTypes again
2943 } else {
2944 // insert all junctions of grid again
2945 WRITE_GLDEBUG("Add junctions during recomputing after calling myNetBuilder->compute(...)");
2946 for (const auto& junction : myAttributeCarriers->getJunctions()) {
2947 // update centering boundary
2948 junction.second->updateCenteringBoundary(false);
2949 // add junction in grid again
2950 addGLObjectIntoGrid(junction.second);
2951 }
2952 // insert all edges from grid again
2953 WRITE_GLDEBUG("Add edges during recomputing after calling myNetBuilder->compute(...)");
2954 for (const auto& edge : myAttributeCarriers->getEdges()) {
2955 // update centeting boundary
2956 edge.second->updateCenteringBoundary(false);
2957 // add edge in grid again
2958 addGLObjectIntoGrid(edge.second);
2959 }
2960 // remake connections
2961 for (const auto& edge : myAttributeCarriers->getEdges()) {
2962 edge.second->remakeGNEConnections(true);
2963 }
2964 // iterate over junctions of net
2965 for (const auto& junction : myAttributeCarriers->getJunctions()) {
2966 // undolist may not yet exist but is also not needed when just marking junctions as valid
2967 junction.second->setLogicValid(true, nullptr);
2968 // updated geometry
2969 junction.second->updateGeometryAfterNetbuild();
2970 // rebuild walking areas
2971 junction.second->rebuildGNEWalkingAreas();
2972 }
2973 // iterate over all edges of net
2974 for (const auto& edge : myAttributeCarriers->getEdges()) {
2975 // update geometry
2976 edge.second->updateGeometry();
2977 }
2978 }
2979 // net recomputed, then return false;
2980 myNeedRecompute = false;
2981}
2982
2983
2984void
2985GNENet::replaceInListAttribute(GNEAttributeCarrier* ac, SumoXMLAttr key, const std::string& which, const std::string& by, GNEUndoList* undoList) {
2986 assert(ac->getTagProperty().getAttributeProperties(key).isList());
2987 std::vector<std::string> values = GNEAttributeCarrier::parse<std::vector<std::string> >(ac->getAttribute(key));
2988 std::vector<std::string> newValues;
2989 bool lastBy = false;
2990 for (auto v : values) {
2991 if (v == which && !lastBy) {
2992 // avoid duplicate occurence of the 'by' edge (i.e. in routes)
2993 newValues.push_back(by);
2994 } else {
2995 newValues.push_back(v);
2996 }
2997 lastBy = v == by;
2998 }
2999 ac->setAttribute(key, toString(newValues), undoList);
3000}
3001
3002
3003/****************************************************************************/
@ MID_COPY_VIEW_GEOBOUNDARY
Copy view geo-coordinate boundary - popup entry.
Definition GUIAppEnum.h:465
@ GLO_NETWORK
The network - empty.
@ MODEPERSONPLAN
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:306
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:296
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define TL(string)
Definition MsgHandler.h:315
#define WRITE_GLDEBUG(msg)
Definition MsgHandler.h:307
std::set< NBEdge * > EdgeSet
container for unique edges
Definition NBCont.h:50
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TRACTION_SUBSTATION
A traction substation.
@ SUMO_TAG_REROUTER
A rerouter.
@ GNE_TAG_MULTI_LANE_AREA_DETECTOR
an e2 detector over multiple lanes (placed here due create Additional Frame)
@ SUMO_TAG_ROUTEPROBE
a routeprobe detector
@ SUMO_TAG_TAZ
a traffic assignment zone
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_ACCESS
An access point for a train stop.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_POI
begin/end of the description of a Point of interest
@ SUMO_TAG_MEANDATA_LANE
a lane based mean data detector
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_OVERHEAD_WIRE_CLAMP
An overhead wire clamp (connection of wires in opposite directions)
@ GNE_TAG_POIGEO
Point of interest over view with GEO attributes.
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_PARKING_AREA
A parking area.
@ GNE_TAG_CALIBRATOR_LANE
A calibrator placed over lane.
@ SUMO_TAG_PARKING_SPACE
A parking space for a single vehicle within a parking area.
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_CROSSING
crossing between edges for pedestrians
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_MEANDATA_EDGE
an edge based mean data detector
@ SUMO_TAG_POLY
begin/end of the description of a polygon
@ SUMO_TAG_OVERHEAD_WIRE_SECTION
An overhead wire section.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_INSTANT_INDUCTION_LOOP
An instantenous induction loop.
@ GNE_TAG_POILANE
Point of interest over Lane.
@ GNE_TAG_JPS_OBSTACLE
polygon used for draw juPedSim obstacles
@ SUMO_TAG_PERSON
@ SUMO_TAG_TYPE
type (edge)
@ SUMO_TAG_VAPORIZER
vaporizer of vehicles
@ SUMO_TAG_LANE_AREA_DETECTOR
alternative tag for e2 detector
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
@ GNE_TAG_JPS_WALKABLEAREA
polygon used for draw juPedSim walkable areas
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
@ SUMO_TAG_ENTRY_EXIT_DETECTOR
alternative tag for e3 detector
@ SUMO_TAG_VSS
A variable speed sign.
@ GNE_TAG_STOPPERSON_EDGE
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
@ STRAIGHT
The link is a straight direction.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_LANE
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_VIA
@ GNE_ATTR_OPPOSITE
to busStop (used by personPlans)
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ARRIVALPOS
@ GNE_ATTR_SELECTED
element is selected
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_EDGES
the edges of a route
@ GNE_ATTR_ADDITIONALCHILDREN
check number of additional children (used in vTypeDistribution)
@ SUMO_ATTR_NUMLANES
@ SUMO_ATTR_LANES
@ GNE_ATTR_DEFAULT_VTYPE
Flag to check if VType is a default VType.
@ GNE_ATTR_MODIFICATION_STATUS
whether a feature has been loaded,guessed,modified or approved
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_TLTYPE
node: the type of traffic light
@ SUMO_ATTR_ENDOFFSET
@ GNE_ATTR_SHAPE_END
last coordinate of edge shape
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_ID
@ GNE_ATTR_DEFAULT_VTYPE_MODIFIED
Flag to check if a default VType was modified.
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_POSITION
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:78
void reset()
Resets the boundary.
Definition Boundary.cpp:66
double getHeight() const
Returns the height of the boundary (y-axis)
Definition Boundary.cpp:160
double getWidth() const
Returns the width of the boudary (x-axis)
Definition Boundary.cpp:154
bool parse()
parse
static void drawBoundary(const GUIVisualizationSettings &s, const Boundary &b)
Draw a boundary (used for debugging)
Definition GLHelper.cpp:966
An Element which don't belong to GNENet but has influence in the simulation.
The main window of Netedit.
OptionsCont & getSumoOptions()
get SUMO options container
void setStatusBarText(const std::string &statusBarText)
set text of the statusBar
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
const std::string & getTagStr() const
get tag assigned to this object in string format
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can't tell (yet)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
bool inGrid() const
check if this AC was inserted in grid
static std::string parseIDs(const std::vector< T > &ACs)
parses a list of specific Attribute Carriers into a string of IDs
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
virtual std::string getAttribute(SumoXMLAttr key) const =0
virtual GUIGlObject * getGUIGlObject()=0
bool isList() const
return true if attribute is a list
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
static void registerJoin(const std::set< NBNode *, ComparatorIdLess > &cluster, NBNodeCont &nc, GNEUndoList *undoList)
change attribute
the function-object for an editing operation (abstract base)
Definition GNEChange.h:56
NBConnection getNBConnection() const
get NBConnection
GNEEdge * getEdgeFrom() const
get the name of the edge the vehicles leave
NBEdge::Connection & getNBEdgeConnection() const
get Edge::Connection
This object is responsible for drawing a shape and for supplying a a popup menu. Messages are routete...
Definition GNECrossing.h:44
GNEJunction * getParentJunction() const
get parent Junction
NBNode::Crossing * getNBCrossing() const
get referente to NBode::Crossing
An Element which don't belong to GNENet but has influence in the simulation.
GNEDataSet * getDataSetParent() const
Returns a pointer to GNEDataSet parent.
const std::vector< GNEGenericData * > & getGenericDataChildren() const
get generic data children
const std::map< const double, GNEDataInterval * > & getDataIntervalChildren() const
get data interval children
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
virtual std::string getAttribute(SumoXMLAttr key) const =0
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:779
GNEEdge * getReverseEdge() const
get reverse edge (if exist)
Definition GNEEdge.cpp:1796
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition GNEEdge.cpp:1116
std::vector< GNEEdge * > getOppositeEdges() const
get opposite edges
Definition GNEEdge.cpp:713
GNEJunction * getFromJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:77
bool wasSplit()
whether this edge was created from a split
Definition GNEEdge.cpp:1128
void copyTemplate(const GNEEdgeTemplate *edgeTemplate, GNEUndoList *undoList)
copy edge attributes from edgetemplate
Definition GNEEdge.cpp:1053
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1122
std::string getAttribute(SumoXMLAttr key) const
Definition GNEEdge.cpp:1134
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:82
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition GNEEdge.cpp:1249
Dialog for edit rerouters.
Dialog for edit rerouters.
An Element which don't belong to GNENet but has influence in the simulation.
GNEDataInterval * getDataIntervalParent() const
get data interval parent
void addChildElement(T *element)
add child element
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
const std::vector< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
void clearInspectedAC()
Clear all current inspected ACs.
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
std::string getAttribute(SumoXMLAttr key) const
void replaceIncomingConnections(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replace one edge by another in all tls connections
void markAsModified(GNEUndoList *undoList)
prevent re-guessing connections at this junction
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
void invalidateTLS(GNEUndoList *undoList, const NBConnection &deletedConnection=NBConnection::InvalidConnection, const NBConnection &addedConnection=NBConnection::InvalidConnection)
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
Position getPositionInView() const
Returns position of hierarchical element in view.
void removeConnectionsFrom(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections from the given edge
bool isValid(SumoXMLAttr key, const std::string &value)
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
void removeEdgeFromCrossings(GNEEdge *edge, GNEUndoList *undoList)
removes the given edge from all pedestrian crossings
NBNode * getNBNode() const
Return net build node.
std::vector< GNEJunction * > getJunctionNeighbours() const
return GNEJunction neighbours
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
void removeConnectionsTo(GNEEdge *edge, GNEUndoList *undoList, bool updateTLS, int lane=-1)
remove all connections to the given edge
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition GNELane.h:46
int getIndex() const
returns the index of the lane
Definition GNELane.cpp:622
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition GNELane.cpp:1955
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition GNELane.cpp:753
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:196
An Element which don't belong to GNENet but has influence in the simulation.
Definition GNEMeanData.h:33
struct used for saving all attribute carriers of net, in different formats
std::vector< GNEEdge * > retrieveEdges(GNEJunction *from, GNEJunction *to) const
get all edges by from and to GNEJunction
GNEEdgeType * registerEdgeType(GNEEdgeType *edgeType)
registers a edge in containers
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
void clearDemandElements()
clear demand elements
GNEEdge * registerEdge(GNEEdge *edge)
registers an edge with containers
GNECrossing * retrieveCrossing(const GUIGlObject *glObject, bool hardFail=true) const
get Crossing by AC
void remapJunctionAndEdgeIds()
remap junction and edge IDs
const std::map< const GNEAttributeCarrier *, GNEDataInterval * > & getDataIntervals() const
get all data intervals of network
void clearAdditionals()
clear additionals
GNEJunction * registerJunction(GNEJunction *junction)
registers a junction in containers
const std::map< SumoXMLTag, std::map< const GUIGlObject *, GNEAdditional * > > & getAdditionals() const
get additionals
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
const std::map< const std::string, GNEDataSet * > & getDataSets() const
get demand elements
const std::map< std::string, GNEEdge * > & getEdges() const
map with the ID and pointer to edges of net
void addDefaultVTypes()
add default VTypes
std::vector< GNEJunction * > getSelectedJunctions() const
return selected junctions
const std::map< SumoXMLTag, std::map< const GUIGlObject *, GNEGenericData * > > & getGenericDatas() const
get all generic datas
const std::map< SumoXMLTag, std::map< const std::string, GNEMeanData * > > & getMeanDatas() const
get meanDatas
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
const std::map< std::string, GNEJunction * > & getJunctions() const
get junctions
const std::map< std::string, GNEEdgeType * > & getEdgeTypes() const
map with the ID and pointer to edgeTypes of net
const std::map< SumoXMLTag, std::map< const GUIGlObject *, GNEDemandElement * > > & getDemandElements() const
get demand elements
void clearJunctions()
clear junctions
GNEConnection * retrieveConnection(const std::string &id, bool hardFail=true) const
get Connection by id
class for GNEChange_ReplaceEdgeInTLS
modul for Saving status
void dataElementsSaved()
mark demand elements as saved
void demandElementsSaved()
mark demand elements as saved
void additionalsSaved()
mark additionals as saved
void TLSSaved()
mark TLS as saved
void meanDatasSaved()
mark mean data elements as saved
void networkSaved()
mark network as saved
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void clearAdditionalElements(GNEUndoList *undoList)
clear additionals
Definition GNENet.cpp:2088
void removeSolitaryJunctions(GNEUndoList *undoList)
removes junctions that have no edges
Definition GNENet.cpp:1737
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList, bool recomputeConnections)
removes edge
Definition GNENet.cpp:423
void writeMeanDatas(OutputDevice &device, SumoXMLTag tag) const
write meanData element by type and sorted by ID
Definition GNENet.cpp:2552
bool joinSelectedJunctions(GNEUndoList *undoList)
join selected junctions
Definition GNENet.cpp:1557
void writeVTypeDistributions(OutputDevice &device, const bool additionalFile) const
write vTypeDistributions sorted by ID
Definition GNENet.cpp:2517
double getDataSetIntervalMaximumEnd() const
get maximum interval
Definition GNENet.cpp:2298
bool writeJuPedSimComment(OutputDevice &device) const
write JuPedSim comment
Definition GNENet.cpp:2681
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNENet.cpp:196
void deleteLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
removes lane
Definition GNENet.cpp:590
bool writeRouteProbeComment(OutputDevice &device) const
write routeProbe comment
Definition GNENet.cpp:2604
static const double Z_INITIALIZED
marker for whether the z-boundary is initialized
Definition GNENet.h:617
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:646
SUMORTree & getGrid()
Returns the RTree used for visualisation speed-up.
Definition GNENet.cpp:155
GNEViewNet * myViewNet
The net to be notified of about changes.
Definition GNENet.h:496
void deleteAdditional(GNEAdditional *additional, GNEUndoList *undoList)
remove additional
Definition GNENet.cpp:664
void disableUpdateGeometry()
disable update geometry of elements after inserting or removing an element in net
Definition GNENet.cpp:2788
void saveDemandElementsConfirmed()
save demand elements after confirming invalid objects
Definition GNENet.cpp:2383
void saveTLSPrograms(const std::string &filename)
save TLS Programs elements of the network
Definition GNENet.cpp:2733
void computeAndUpdate(OptionsCont &neteditOptions, bool volatileOptions)
recompute the network and update lane geometries
Definition GNENet.cpp:2880
NBNetBuilder * getNetBuilder() const
get net builder
Definition GNENet.cpp:1551
void saveAdditionalsConfirmed()
save additionals after confirming invalid objects
Definition GNENet.cpp:2323
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1378
bool writeMeanDataLaneComment(OutputDevice &device) const
write Wire comment
Definition GNENet.cpp:2723
void reverseEdge(GNEEdge *edge, GNEUndoList *undoList)
reverse edge
Definition GNENet.cpp:1057
bool writeTAZComment(OutputDevice &device) const
write TAZ comment
Definition GNENet.cpp:2693
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1388
void saveJoined(const std::string &filename)
save log of joined junctions (and nothing else)
Definition GNENet.cpp:1352
NBTrafficLightLogicCont & getTLLogicCont()
returns the tllcont of the underlying netbuilder
Definition GNENet.cpp:2153
bool restrictLane(SUMOVehicleClass vclass, GNELane *lane, GNEUndoList *undoList)
transform lane to restricted lane
Definition GNENet.cpp:796
GNENetHelper::SavingStatus * getSavingStatus() const
get saving status
Definition GNENet.cpp:131
void enableUpdateData()
Definition GNENet.cpp:2800
void setViewNet(GNEViewNet *viewNet)
Set the net to be notified of network changes.
Definition GNENet.cpp:1360
bool writeCalibratorComment(OutputDevice &device) const
write calibrator comment
Definition GNENet.cpp:2614
bool myNeedRecompute
whether the net needs recomputation
Definition GNENet.h:520
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition GNENet.cpp:685
void duplicateLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
duplicates lane
Definition GNENet.cpp:780
const Boundary & getZBoundary() const
Returns the Z boundary (stored in the x() coordinate) values of 0 do not affect the boundary.
Definition GNENet.cpp:208
const Boundary & getBoundary() const
returns the bounder of the network
Definition GNENet.cpp:148
void saveEdgeTypes(const std::string &filename)
save edgeTypes elements of the network
Definition GNENet.cpp:2754
void deleteNetworkElement(GNENetworkElement *networkElement, GNEUndoList *undoList)
delete network element
Definition GNENet.cpp:336
void saveAdditionals()
save additional elements
Definition GNENet.cpp:2177
SUMORTree myGrid
the rtree which contains all GUIGlObjects (so named for historical reasons)
Definition GNENet.h:490
void writeVTypes(OutputDevice &device, const bool additionalFile) const
write vTypes sorted by ID
Definition GNENet.cpp:2535
void clearDataElements(GNEUndoList *undoList)
clear data elements
Definition GNENet.cpp:2114
void deleteDataInterval(GNEDataInterval *dataInterval, GNEUndoList *undoList)
remove data interval
Definition GNENet.cpp:728
void deleteConnection(GNEConnection *connection, GNEUndoList *undoList)
remove connection
Definition GNENet.cpp:631
void clearDemandElements(GNEUndoList *undoList)
clear demand elements
Definition GNENet.cpp:2101
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:142
bool writeMeanDataEdgeComment(OutputDevice &device) const
write meanDataEdge comment
Definition GNENet.cpp:2713
void adjustPersonPlans(GNEUndoList *undoList)
adjust person plans
Definition GNENet.cpp:1843
void computeNetwork(GNEApplicationWindow *window, bool force=false, bool volatileOptions=false)
trigger full netbuild computation param[in] window The window to inform about delay param[in] force W...
Definition GNENet.cpp:1398
void writeRoutes(OutputDevice &device, const bool additionalFile) const
write route sorted by ID
Definition GNENet.cpp:2502
void cleanInvalidDemandElements(GNEUndoList *undoList)
clean invalid demand elements
Definition GNENet.cpp:1888
bool myUpdateDataEnabled
Flag to enable or disable update data elements after inserting or removing element in net.
Definition GNENet.h:526
void cleanUnusedRoutes(GNEUndoList *undoList)
clean unused routes
Definition GNENet.cpp:1753
NBNetBuilder * myNetBuilder
The internal netbuilder.
Definition GNENet.h:493
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition GNENet.cpp:2171
void computeJunction(GNEJunction *junction)
trigger recomputation of junction shape and logic param[in] window The window to inform about delay
Definition GNENet.cpp:1515
void resetJunctionConnections(GNEJunction *junction, GNEUndoList *undoList)
reset junction's connections
Definition GNENet.cpp:2077
void deleteMeanData(GNEMeanData *meanData, GNEUndoList *undoList)
remove generic data
Definition GNENet.cpp:771
void replaceIncomingEdge(GNEEdge *which, GNEEdge *by, GNEUndoList *undoList)
replaces edge
Definition GNENet.cpp:497
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition GNENet.cpp:189
void deleteGenericData(GNEGenericData *genericData, GNEUndoList *undoList)
remove generic data
Definition GNENet.cpp:741
std::pair< GNEJunction *, GNEEdge * > splitEdge(GNEEdge *edge, const Position &pos, GNEUndoList *undoList, GNEJunction *newJunction=0)
split edge at position by inserting a new junction
Definition GNENet.cpp:916
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:125
GNEEdge * addReversedEdge(GNEEdge *edge, const bool disconnected, GNEUndoList *undoList)
add reversed edge
Definition GNENet.cpp:1070
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition GNENet.cpp:2138
bool myUpdateGeometryEnabled
Flag to enable or disable update geometry of elements after inserting or removing element in net.
Definition GNENet.h:523
void initJunctionsAndEdges()
Init Junctions and edges.
Definition GNENet.cpp:2826
bool writeWireComment(OutputDevice &device) const
write Wire comment
Definition GNENet.cpp:2703
void splitEdgesBidi(GNEEdge *edge, GNEEdge *oppositeEdge, const Position &pos, GNEUndoList *undoList)
split all edges at position by inserting one new junction
Definition GNENet.cpp:1033
GNENetHelper::SavingStatus * mySavingStatus
AttributeCarriers of net.
Definition GNENet.h:502
void saveDemandElements()
save demand element elements of the network
Definition GNENet.cpp:2230
void clearMeanDataElements(GNEUndoList *undoList)
clear meanDatas
Definition GNENet.cpp:2125
unsigned int myEdgeIDCounter
Definition GNENet.h:513
void expandBoundary(const Boundary &newBoundary)
expand boundary
Definition GNENet.cpp:202
void disableUpdateData()
disable update data elements after inserting or removing an element in net
Definition GNENet.cpp:2811
bool removeRestrictedLane(SUMOVehicleClass vclass, GNEEdge *edge, GNEUndoList *undoList)
remove restricted lane
Definition GNENet.cpp:902
void saveDataElements()
save data set elements of the network
Definition GNENet.cpp:2270
~GNENet()
Destructor.
Definition GNENet.cpp:110
void mergeJunctions(GNEJunction *moved, GNEJunction *target, GNEUndoList *undoList)
merge the given junctions edges between the given junctions will be deleted
Definition GNENet.cpp:1108
GNEEdge * createEdge(GNEJunction *src, GNEJunction *dest, GNEEdge *edgeTemplate, 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:239
std::set< std::string > myExplicitTurnarounds
list of edge ids for which turn-arounds must be added explicitly
Definition GNENet.h:517
void saveJuPedSimElements(const std::string &file)
save JuPedSim elements
Definition GNENet.cpp:2216
const std::map< std::string, int > & getEdgesAndNumberOfLanes() const
et edges and number of lanes
Definition GNENet.cpp:160
bool writeStoppingPlaceComment(OutputDevice &device) const
write stoppingPlace comment
Definition GNENet.cpp:2626
void addZValueInBoundary(const double z)
add Z in net boundary
Definition GNENet.cpp:214
static const std::map< SumoXMLAttr, std::string > EMPTY_HEADER
variable used for write headers in additional, demand and data elements
Definition GNENet.h:486
void writeRouteDistributions(OutputDevice &device, const bool additionalFile) const
write route distributions sorted by ID
Definition GNENet.cpp:2484
bool isUpdateGeometryEnabled() const
check if update geometry after inserting or removing has to be updated
Definition GNENet.cpp:2794
bool addRestrictedLane(SUMOVehicleClass vclass, GNEEdge *edge, int index, GNEUndoList *undoList)
add restricted lane to edge
Definition GNENet.cpp:849
void saveNetwork()
save the network
Definition GNENet.cpp:1309
bool checkJunctionPosition(const Position &pos)
return true if there are already a Junction in the given position, false in other case
Definition GNENet.cpp:1297
bool addGreenVergeLane(GNEEdge *edge, int index, GNEUndoList *undoList)
add restricted lane to edge
Definition GNENet.cpp:885
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition GNENet.cpp:179
bool isNetRecomputed() const
check if net require recomputing
Definition GNENet.cpp:1539
void writeAdditionalByType(OutputDevice &device, const std::vector< SumoXMLTag > tags) const
write additional element by type and sorted by ID
Definition GNENet.cpp:2454
GNEPathManager * myNetworkPathManager
Network path manager.
Definition GNENet.h:505
bool isUpdateDataEnabled() const
check if update data after inserting or removing has to be updated
Definition GNENet.cpp:2817
bool writeShapesComment(OutputDevice &device) const
write shape comment
Definition GNENet.cpp:2667
void deleteDataSet(GNEDataSet *dataSet, GNEUndoList *undoList)
remove data set
Definition GNENet.cpp:715
static void replaceInListAttribute(GNEAttributeCarrier *ac, SumoXMLAttr key, const std::string &which, const std::string &by, GNEUndoList *undoList)
replace in list attribute
Definition GNENet.cpp:2985
bool cleanInvalidCrossings(GNEUndoList *undoList)
clear invalid crossings
Definition GNENet.cpp:1684
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:137
void splitJunction(GNEJunction *junction, bool reconnect, GNEUndoList *undoList)
replace the selected junction by a list of junctions for each unique edge endpoint
Definition GNENet.cpp:1981
void selectRoundabout(GNEJunction *junction, GNEUndoList *undoList)
select all roundabout edges and junctions for the current roundabout
Definition GNENet.cpp:1141
void joinRoutes(GNEUndoList *undoList)
join routes
Definition GNENet.cpp:1779
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition GNENet.cpp:166
bool writeRouteComment(OutputDevice &device, const bool additionalFile) const
write route comment
Definition GNENet.cpp:2589
bool writeVTypeComment(OutputDevice &device, const bool additionalFile) const
write vType comment
Definition GNENet.cpp:2567
void replaceJunctionByGeometry(GNEJunction *junction, GNEUndoList *undoList)
replace the selected junction by geometry node(s) and merge the edges
Definition GNENet.cpp:1927
bool writeDetectorComment(OutputDevice &device) const
write detector comment
Definition GNENet.cpp:2638
void createRoundabout(GNEJunction *junction, GNEUndoList *undoList)
transform the given junction into a roundabout
Definition GNENet.cpp:1160
void writeDemandByType(OutputDevice &device, SumoXMLTag tag) const
write demand element by type and sorted by ID
Definition GNENet.cpp:2472
void requireRecompute()
inform the net about the need for recomputation
Definition GNENet.cpp:1533
GNEJunction * createJunction(const Position &pos, GNEUndoList *undoList)
creates a new junction
Definition GNENet.cpp:223
unsigned int myJunctionIDCounter
Definition GNENet.h:512
bool writeOtherAdditionalsComment(OutputDevice &device) const
write other additional comment
Definition GNENet.cpp:2650
std::map< std::string, int > myEdgesAndNumberOfLanes
map with the Edges and their number of lanes
Definition GNENet.h:614
GNEPathManager * myDemandPathManager
Demand path manager.
Definition GNENet.h:508
void saveMeanDatasConfirmed()
save meanDatas
Definition GNENet.cpp:2436
void addExplicitTurnaround(std::string id)
add edge id to the list of explicit turnarounds
Definition GNENet.cpp:2165
void initGNEConnections()
initialize GNEConnections
Definition GNENet.cpp:2867
void deleteJunction(GNEJunction *junction, GNEUndoList *undoList)
removes junction and all incident edges
Definition GNENet.cpp:377
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition GNENet.cpp:2159
void savePlain(const std::string &prefix)
save plain xml representation of the network (and nothing else)
Definition GNENet.cpp:1343
GNENetHelper::AttributeCarriers * myAttributeCarriers
AttributeCarriers of net.
Definition GNENet.h:499
void computeDataElements(GNEApplicationWindow *window)
compute data elements param[in] window The window to inform about delay
Definition GNENet.cpp:1502
FXApp * getApp()
get pointer to the main App
Definition GNENet.cpp:1545
int getNumberOfTLSPrograms() const
get number of TLS Programs
Definition GNENet.cpp:2748
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2147
void saveDataElementsConfirmed()
save data elements after confirming invalid objects
Definition GNENet.cpp:2421
void enableUpdateGeometry()
Definition GNENet.cpp:2782
void clearJunctionConnections(GNEJunction *junction, GNEUndoList *undoList)
clear junction's connections
Definition GNENet.cpp:2065
void saveMeanDatas()
save meanData elements of the network
Definition GNENet.cpp:2315
Boundary myZBoundary
the z boundary (stored in the x-coordinate), values of 0 are ignored
Definition GNENet.h:611
double getDataSetIntervalMinimumBegin() const
get minimum interval
Definition GNENet.cpp:2281
void computeDemandElements(GNEApplicationWindow *window)
compute demand elements param[in] window The window to inform about delay
Definition GNENet.cpp:1482
GUIGlObject * getGUIGlObject()
get GUIGlObject associated with this AttributeCarrier
void updatePathCalculator()
update DijkstraRouter (needed a good calculation of dijkstra path after modifying network)
bool isPathCalculatorUpdated() const
check if pathCalculator is updated
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void invalidateJunctionPath(const GNEJunction *junction)
invalidate junction path
void clearSegments()
clear segments
void invalidateLanePath(const GNELane *lane)
invalidate lane path
bool isShapeElement() const
return true if tag correspond to a shape
const GNEAttributeProperties & getAttributeProperties(SumoXMLAttr attr) const
get attribute (throw error if doesn't exist)
bool isPlacedInRTree() const
return true if Tag correspond to an element that has to be placed in RTREE
bool isStoppingPlace() const
additional elements
bool isCalibrator() const
return true if tag correspond to a calibrator (Only used to group all detectors in the XML)
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isDetector() const
return true if tag correspond to a shape (Only used to group all detectors in the XML)
bool isJuPedSimElement() const
return true if tag correspond to a JuPedSim element
bool isAdditionalPureElement() const
return true if tag correspond to a pure additional element
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
The popup menu of a globject.
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
void setNetObject(GUIGlObject *object)
Sets the given object as the "network" object.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
A window containing a gl-object's parameter.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
void destroyPopup()
destroys the popup
Stores the information about how to visualize structures.
bool parse()
parse
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
const Boundary & getConvBoundary() const
Returns the converted boundary.
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Storage for edges, including some functionality operating on multiple edges.
Definition NBEdgeCont.h:59
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
std::vector< std::string > getAllNames() const
Returns all ids of known edges.
The representation of a single edge during network building.
Definition NBEdge.h:92
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition NBEdge.cpp:4378
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition NBEdge.h:1041
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition NBEdge.h:602
void reinitNodes(NBNode *from, NBNode *to)
Resets nodes but keeps all other values the same (used when joining)
Definition NBEdge.cpp:437
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:546
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition NBEdge.h:355
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1428
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition NBEdge.h:783
EdgeBuildingStep getStep() const
The building step of this edge.
Definition NBEdge.h:635
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition NBEdge.h:612
@ LANES2LANES_RECHECK
Lanes to lanes - relationships are computed; should be rechecked.
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:520
void resetNodeBorder(const NBNode *node)
Definition NBEdge.cpp:738
double getTotalWidth() const
Returns the combined width of all lanes of this edge.
Definition NBEdge.cpp:4216
std::string getLaneID(int lane) const
get lane ID
Definition NBEdge.cpp:4016
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:609
int getPriority() const
Returns the priority of the edge.
Definition NBEdge.h:527
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition NBEdge.h:349
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition NBEdge.cpp:590
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition NBEdge.cpp:4714
Instance responsible for building networks.
NBNodeCont & getNodeCont()
Returns a reference to the node container.
NBEdgeCont & getEdgeCont()
NBTypeCont & getTypeCont()
Returns a reference to the type container.
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
void compute(OptionsCont &oc, const std::set< std::string > &explicitTurnarounds=std::set< std::string >(), bool mayAddOrRemove=true)
Performs the network building steps.
A definition of a pedestrian crossing.
Definition NBNode.h:135
PositionVector customShape
optional customShape for this crossing
Definition NBNode.h:160
int customTLIndex
the custom traffic light index of this crossing (if controlled)
Definition NBNode.h:165
bool priority
whether the pedestrians have priority
Definition NBNode.h:158
EdgeVector edges
The edges being crossed.
Definition NBNode.h:142
double width
This crossing's width.
Definition NBNode.h:150
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
std::vector< std::string > getAllNames() const
get all node names
void analyzeCluster(NodeSet cluster, std::string &id, Position &pos, bool &hasTLS, TrafficLightType &type, SumoXMLNodeType &nodeType)
Represents a single node (junction) during network building.
Definition NBNode.h:66
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
Definition NBNode.cpp:2358
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:336
static const double UNSPECIFIED_RADIUS
unspecified lane width
Definition NBNode.h:220
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition NBNode.h:268
std::vector< std::pair< Position, std::string > > getEndPoints() const
return list of unique endpoint coordinates of all edges at this node
Definition NBNode.cpp:4122
std::vector< std::pair< NBEdge *, NBEdge * > > getEdgesToJoin() const
get edges to join
Definition NBNode.cpp:2580
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition NBNode.h:273
const Position & getPosition() const
Definition NBNode.h:260
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Definition NBNode.h:278
void updateSurroundingGeometry()
update geometry of node and surrounding edges
Definition NBNode.cpp:1142
double getRadius() const
Returns the turning radius of this node.
Definition NBNode.h:290
bool checkIsRemovable() const
check if node is removable
Definition NBNode.cpp:2497
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition NBNode.h:331
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node's edges clockwise regarding driving direction.
A container for traffic light definitions and built programs.
bool computeSingleLogic(OptionsCont &oc, NBTrafficLightDefinition *def)
Computes a specific traffic light logic (using by netedit)
void writeEdgeTypes(OutputDevice &into, const std::set< std::string > &typeIDs=std::set< std::string >()) const
writes all EdgeTypes (and their lanes) as XML
void insertEdgeType(const std::string &id, int numLanes, double maxSpeed, int prio, SVCPermissions permissions, LaneSpreadFunction spreadType, double width, bool oneWayIsDefault, double sidewalkWidth, double bikeLaneWidth, double widthResolution, double maxWidth, double minWidth)
Adds a edgeType into the list.
void clearTypes()
clear types
void insertLaneType(const std::string &edgeTypeID, int index, double maxSpeed, SVCPermissions permissions, double width, const std::set< SumoXMLAttr > &attrs)
Adds a laneType into the list.
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network stored in the given net builder.
Definition NWFrame.cpp:188
static void writeTrafficLights(OutputDevice &into, const NBTrafficLightLogicCont &tllCont)
writes the traffic light logics to the given device
static void writeJoinedJunctions(const std::string &filename, NBNodeCont &nc)
Writes the joined-juncionts to file.
static void writeNetwork(const OptionsCont &oc, const std::string &prefix, NBNetBuilder &nb)
Writes the network into XML-files (nodes, edges, connections, traffic lights)
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void resetWritable()
Resets all options to be writeable.
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
void setx(double x)
set position x
Definition Position.h:70
double x() const
Returns the x-position.
Definition Position.h:55
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
Definition Position.h:286
void sety(double y)
set position y
Definition Position.h:75
double y() const
Returns the y-position.
Definition Position.h:60
A list of positions.
void append(const PositionVector &v, double sameThreshold=2.0)
double length() const
Returns the length.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
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.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
void push_back_noDoublePos(const Position &p)
insert in back a non double position
PositionVector reverse() const
reverse position vector
A RT-tree for efficient storing of SUMO's GL-objects.
Definition SUMORTree.h:66
void addAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Adds an additional object (detector/shape/trigger) for visualisation.
Definition SUMORTree.h:124
void removeAdditionalGLObject(GUIGlObject *o, const double exaggeration=1)
Removes an additional object (detector/shape/trigger) from being visualised.
Definition SUMORTree.h:162
static std::string trim(const std::string s, const std::string &t=" \t\n")
remove leading and trailing whitespace
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition json.hpp:4471
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
A structure which describes a connection between edges or lanes.
Definition NBEdge.h:201
An (internal) definition of a single lane of an edge.
Definition NBEdge.h:143