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