long GNEConnectorFrame::onCmdClearSelectedConnections(FXObject*, FXSelector, void*) { onCmdCancel(0, 0, 0); myViewNet->getUndoList()->p_begin("clear connections from selected lanes, edges and junctions"); const std::set<GUIGlID> ids = gSelected.getSelected(); for (std::set<GUIGlID>::const_iterator it = ids.begin(); it != ids.end(); it++) { GUIGlID id = *it; GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(id); if (object) { switch (object->getType()) { case GLO_JUNCTION: { GNEJunction* junction = dynamic_cast<GNEJunction*>(object); junction->setLogicValid(false, myViewNet->getUndoList()); // clear connections junction->setLogicValid(false, myViewNet->getUndoList(), GNEAttributeCarrier::MODIFIED); // prevent re-guessing break; } case GLO_EDGE: { const GNEEdge::LaneVector& lanes = dynamic_cast<GNEEdge*>(object)->getLanes(); for (GNEEdge::LaneVector::const_iterator l_it = lanes.begin(); l_it != lanes.end(); ++l_it) { removeConnections(*l_it); } break; } case GLO_LANE: removeConnections(dynamic_cast<GNELane*>(object)); break; default: break; } } } myViewNet->getUndoList()->p_end(); return 1; }
GNEEdge* GNENet::addReversedEdge(GNEEdge* edge, GNEUndoList* undoList) { undoList->p_begin("add reversed edge"); GNEEdge* reversed = 0; if (edge->getNBEdge()->getLaneSpreadFunction() == LANESPREAD_RIGHT) { GNEEdge* reversed = createEdge(edge->getDest(), edge->getSource(), edge, undoList, "-" + edge->getID(), false, true); assert(reversed != 0); reversed->setAttribute(SUMO_ATTR_SHAPE, toString(edge->getNBEdge()->getInnerGeometry().reverse()), undoList); } else { // if the edge is centered it should probably connect somewhere else // make it easy to move and reconnect it PositionVector orig = edge->getNBEdge()->getGeometry(); PositionVector origInner = edge->getNBEdge()->getInnerGeometry(); const SUMOReal tentativeShift = edge->getNBEdge()->getTotalWidth() + 2; orig.move2side(-tentativeShift); origInner.move2side(-tentativeShift); GNEJunction* src = createJunction(orig.back(), undoList); GNEJunction* dest = createJunction(orig.front(), undoList); GNEEdge* reversed = createEdge(src, dest, edge, undoList, "-" + edge->getID(), false, true); assert(reversed != 0); reversed->setAttribute(SUMO_ATTR_SHAPE, toString(origInner.reverse()), undoList); // select the new edge and its nodes std::set<GUIGlID> toSelect; toSelect.insert(reversed->getGlID()); toSelect.insert(src->getGlID()); toSelect.insert(dest->getGlID()); undoList->add(new GNEChange_Selection(toSelect, gSelected.getSelected(), true), true); } undoList->p_end(); return reversed; }
// =========================================================================== // method definitions // =========================================================================== GNECrossing::GNECrossing(GNEJunction& parentJunction, const std::string& id) : GNENetElement(parentJunction.getNet(), id, GLO_CROSSING, SUMO_TAG_CROSSING), myParentJunction(parentJunction), myCrossing(parentJunction.getNBNode()->getCrossing(id)), myShape(myCrossing.shape) { // Update geometry updateGeometry(); }
void GNEConnectorFrame::handleLaneClick(GNELane* lane, bool mayDefinitelyPass, bool allowConflict, bool toggle) { if (myCurrentLane == 0) { myCurrentLane = lane; myCurrentLane->setSpecialColor(&sourceColor); initTargets(); buildIinternalLanes(lane->getParentEdge().getNBEdge()->getToNode()); myNumChanges = 0; myViewNet->getUndoList()->p_begin("modify connections"); } else if (myPotentialTargets.count(lane) || allowConflict) { const unsigned int fromIndex = myCurrentLane->getIndex(); GNEEdge& srcEdge = myCurrentLane->getParentEdge(); GNEEdge& destEdge = lane->getParentEdge(); const std::string& destEdgeID = destEdge.getMicrosimID(); std::vector<NBEdge::Connection> connections = srcEdge.getNBEdge()->getConnectionsFromLane(fromIndex); bool changed = false; NBConnection deletedConnection = NBConnection::InvalidConnection; LaneStatus status = getLaneStatus(connections, lane); if (status == CONFLICTED && allowConflict) { status = UNCONNECTED; } switch (status) { case UNCONNECTED: if (toggle) { myViewNet->getUndoList()->add(new GNEChange_Connection(&srcEdge, fromIndex, destEdgeID, lane->getIndex(), mayDefinitelyPass, true), true); lane->setSpecialColor(mayDefinitelyPass ? &targetPassColor : &targetColor); changed = true; } break; case CONNECTED: case CONNECTED_PASS: myViewNet->getUndoList()->add(new GNEChange_Connection(&srcEdge, fromIndex, destEdgeID, lane->getIndex(), status == CONNECTED_PASS, false), true); lane->setSpecialColor(&potentialTargetColor); changed = true; deletedConnection = NBConnection(srcEdge.getNBEdge(), fromIndex, destEdge.getNBEdge(), lane->getIndex(), (int)getTLLLinkNumber(connections, lane)); break; case CONFLICTED: myViewNet->setStatusBarText("Another lane from the same edge already connects to that lane"); break; } if (changed) { myNumChanges += 1; GNEJunction* affected = myViewNet->getNet()->retrieveJunction(srcEdge.getDest()->getMicrosimID()); affected->invalidateTLS(myViewNet->getUndoList(), deletedConnection); buildIinternalLanes(myCurrentLane->getParentEdge().getNBEdge()->getToNode()); } } else { myViewNet->setStatusBarText("Invalid target for connection"); } updateDescription(); }
long GNETLSEditorFrame::onCmdDefCreate(FXObject*, FXSelector, void*) { GNEJunction* junction = myCurrentJunction; onCmdCancel(0, 0, 0); // abort because we onCmdOk assumes we wish to save an edited definition if (junction->getAttribute(SUMO_ATTR_TYPE) != toString(NODETYPE_TRAFFIC_LIGHT)) { junction->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_TRAFFIC_LIGHT), myViewNet->getUndoList()); } else { myViewNet->getUndoList()->add(new GNEChange_TLS(junction, 0, true, true), true); } editJunction(junction); return 1; }
long GNETLSEditorFrame::onCmdDefDelete(FXObject*, FXSelector, void*) { GNEJunction* junction = myCurrentJunction; const bool changeType = myDefinitions.size() == 1; onCmdCancel(0, 0, 0); // abort because onCmdOk assumes we wish to save an edited definition if (changeType) { junction->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_PRIORITY), myViewNet->getUndoList()); } else { NBTrafficLightDefinition* tlDef = myDefinitions[myProgramComboBox->getCurrentItem()]; myViewNet->getUndoList()->add(new GNEChange_TLS(junction, tlDef, false), true); } return 1; }
void GNENet::removeSolitaryJunctions(GNEUndoList* undoList) { undoList->p_begin("Clean junctions"); std::vector<GNEJunction*> toRemove; for (GNEJunctions::const_iterator it = myJunctions.begin(); it != myJunctions.end(); it++) { GNEJunction* junction = it->second; if (junction->getNBNode()->getEdges().size() == 0) { toRemove.push_back(junction); } } for (std::vector<GNEJunction*>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) { deleteJunction(*it, undoList); } undoList->p_end(); }
void GNENet::joinSelectedJunctions(GNEUndoList* undoList) { std::vector<GNEJunction*> selected = retrieveJunctions(true); if (selected.size() < 2) { return; } undoList->p_begin("Join selected junctions"); EdgeVector allIncoming; EdgeVector allOutgoing; std::set<NBNode*> cluster; for (std::vector<GNEJunction*>::iterator it = selected.begin(); it != selected.end(); it++) { cluster.insert((*it)->getNBNode()); const EdgeVector& incoming = (*it)->getNBNode()->getIncomingEdges(); allIncoming.insert(allIncoming.end(), incoming.begin(), incoming.end()); const EdgeVector& outgoing = (*it)->getNBNode()->getOutgoingEdges(); allOutgoing.insert(allOutgoing.end(), outgoing.begin(), outgoing.end()); } // create new junction Position pos; bool setTL; std::string id; TrafficLightType type; myNetBuilder->getNodeCont().analyzeCluster(cluster, id, pos, setTL, type); // XXX this is not undone when calling 'undo' myNetBuilder->getNodeCont().registerJoinedCluster(cluster); GNEJunction* joined = createJunction(pos, undoList); if (setTL) { joined->setAttribute(SUMO_ATTR_TYPE, toString(NODETYPE_TRAFFIC_LIGHT), undoList); // XXX ticket831 //joined-><getTrafficLight>->setAttribute(SUMO_ATTR_TYPE, toString(type), undoList); } // remap edges for (EdgeVector::const_iterator it = allIncoming.begin(); it != allIncoming.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, oldEdge->getSource(), joined, undoList, true); } for (EdgeVector::const_iterator it = allOutgoing.begin(); it != allOutgoing.end(); it++) { GNEEdge* oldEdge = myEdges[(*it)->getID()]; remapEdge(oldEdge, joined, oldEdge->getDest(), undoList, true); } // delete original junctions for (std::vector<GNEJunction*>::iterator it = selected.begin(); it != selected.end(); it++) { deleteJunction(*it, undoList); } joined->setAttribute(SUMO_ATTR_ID, id, undoList); undoList->p_end(); }
long GNEConnectorFrame::onCmdResetSelectedConnections(FXObject*, FXSelector, void*) { onCmdCancel(0, 0, 0); myViewNet->getUndoList()->p_begin("reset connections from selected lanes"); const std::set<GUIGlID> nodeIDs = gSelected.getSelected(GLO_JUNCTION); for (std::set<GUIGlID>::const_iterator nid_it = nodeIDs.begin(); nid_it != nodeIDs.end(); nid_it++) { GUIGlObject* object = GUIGlObjectStorage::gIDStorage.getObjectBlocking(*nid_it); if (object) { GNEJunction* junction = dynamic_cast<GNEJunction*>(object); if (junction) { junction->setLogicValid(false, myViewNet->getUndoList()); } else { throw ProcessError("Wrong object type returned from gIDStorage"); } } } myViewNet->getUndoList()->p_end(); return 1; }
// =========================================================================== // method definitions // =========================================================================== GNECrossing::GNECrossing(GNEJunction& parentJunction, const std::string& id) : GUIGlObject(GLO_CROSSING, id), GNEAttributeCarrier(SUMO_TAG_CROSSING), myParentJunction(parentJunction), myCrossing(parentJunction.getNBNode()->getCrossing(id)), myShape(myCrossing.shape) { int segments = (int) myShape.size() - 1; if (segments >= 0) { myShapeRotations.reserve(segments); myShapeLengths.reserve(segments); for (int i = 0; i < segments; ++i) { const Position& f = myShape[i]; const Position& s = myShape[i + 1]; myShapeLengths.push_back(f.distanceTo2D(s)); myShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI); } } }
void GNEFrame::ACHierarchy::showAttributeCarrierChilds(GNEAttributeCarrier *AC, FXTreeItem* itemParent) { // Switch gl type of ac switch (AC->getTag()) { case SUMO_TAG_JUNCTION: { // retrieve junction GNEJunction* junction = myFrameParent->getViewNet()->getNet()->retrieveJunction(AC->getID(), false); if(junction) { // insert junction item FXTreeItem* junctionItem = addACIntoList(AC, itemParent); // insert edges for (auto i : junction->getGNEEdges()) { showAttributeCarrierChilds(i, junctionItem); } // insert crossings for (auto i : junction->getGNECrossings()) { showAttributeCarrierChilds(i, junctionItem); } } break; } case SUMO_TAG_EDGE: { // retrieve edge GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(AC->getID(), false); if(edge) { // insert edge item FXTreeItem* edgeItem = addACIntoList(AC, itemParent); // insert lanes for (int i = 0; i < (int)edge->getLanes().size(); i++) { showAttributeCarrierChilds(edge->getLanes().at(i), edgeItem); } // insert additionals of edge for (auto i : edge->getAdditionalChilds()) { showAttributeCarrierChilds(i, edgeItem); } } break; } case SUMO_TAG_LANE: { // retrieve lane GNELane* lane = myFrameParent->getViewNet()->getNet()->retrieveLane(AC->getID(), false); if(lane) { // insert lane item FXTreeItem* laneItem = addACIntoList(AC, itemParent); // insert additionals of lanes for (auto i : lane->getAdditionalChilds()) { showAttributeCarrierChilds(i, laneItem); } // insert incoming connections of lanes (by default isn't expanded) if (lane->getGNEIncomingConnections().size() > 0) { std::vector<GNEConnection*> incomingLaneConnections = lane->getGNEIncomingConnections(); FXTreeItem* incomingConnections = myTreelist->insertItem(0, laneItem, "Incomings", incomingLaneConnections.front()->getIcon(), lane->getGNEIncomingConnections().front()->getIcon()); myTreeItemsConnections.insert(incomingConnections); incomingConnections->setExpanded(false); // insert incoming connections for (auto i : incomingLaneConnections) { showAttributeCarrierChilds(i, incomingConnections); } } // insert outcoming connections of lanes (by default isn't expanded) if (lane->getGNEOutcomingConnections().size() > 0) { std::vector<GNEConnection*> outcomingLaneConnections = lane->getGNEOutcomingConnections(); FXTreeItem* outgoingConnections = myTreelist->insertItem(0, laneItem, "Outcomings", outcomingLaneConnections.front()->getIcon(), lane->getGNEOutcomingConnections().front()->getIcon()); myTreeItemsConnections.insert(outgoingConnections); outgoingConnections->setExpanded(false); // insert outcoming connections for (auto i : outcomingLaneConnections) { showAttributeCarrierChilds(i, outgoingConnections); } } } break; } case SUMO_TAG_POI: case SUMO_TAG_POLY: case SUMO_TAG_CROSSING: case SUMO_TAG_CONNECTION: { // insert connection item addACIntoList(AC, itemParent); break; } default: { // check if is an additional if(GNEAttributeCarrier::getTagProperties(AC->getTag()).isAdditional()) { // retrieve additional GNEAdditional *additional = myFrameParent->getViewNet()->getNet()->retrieveAdditional(AC->getTag(), AC->getID(), false); if(additional) { // insert additional item FXTreeItem* additionalItem = addACIntoList(AC, itemParent); // insert additionals childs for (auto i : additional->getAdditionalChilds()) { showAttributeCarrierChilds(i, additionalItem); } } } break; } } }
FXTreeItem* GNEFrame::ACHierarchy::showAttributeCarrierParents() { // Switch gl type of ac switch (myAC->getTag()) { case SUMO_TAG_EDGE: { // obtain Edge GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(myAC->getID(), false); if(edge) { // insert Junctions of edge in tree (Pararell because a edge has always two Junctions) FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " origin").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " destiny").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); junctionDestinyItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionSourceItem] = edge->getGNEJunctionSource(); myTreeItemToACMap[junctionDestinyItem] = edge->getGNEJunctionDestiny(); // return junction destiny Item return junctionDestinyItem; } else { return nullptr; } } case SUMO_TAG_LANE: { // obtain lane GNELane* lane = myFrameParent->getViewNet()->getNet()->retrieveLane(myAC->getID(), false); if(lane) { // obtain edge parent GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(lane->getParentEdge().getID()); //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions) FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " origin").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " destiny").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); junctionDestinyItem->setExpanded(true); // Create edge item FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon()); edgeItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionSourceItem] = edge->getGNEJunctionSource(); myTreeItemToACMap[junctionDestinyItem] = edge->getGNEJunctionDestiny(); myTreeItemToACMap[edgeItem] = edge; // return edge item return edgeItem; } else { return nullptr; } } case SUMO_TAG_POILANE: { // Obtain POILane GNEPOI* POILane = myFrameParent->getViewNet()->getNet()->retrievePOI(myAC->getID(), false); if(POILane) { // obtain lane parent GNELane* lane = myFrameParent->getViewNet()->getNet()->retrieveLane(POILane->getLane()->getID()); // obtain edge parent GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(lane->getParentEdge().getID()); //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions) FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " origin").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " destiny").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); junctionDestinyItem->setExpanded(true); // Create edge item FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon()); edgeItem->setExpanded(true); // Create lane item FXTreeItem* laneItem = myTreelist->insertItem(0, edgeItem, lane->getHierarchyName().c_str(), lane->getIcon(), lane->getIcon()); laneItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionSourceItem] = edge->getGNEJunctionSource(); myTreeItemToACMap[junctionDestinyItem] = edge->getGNEJunctionDestiny(); myTreeItemToACMap[edgeItem] = edge; myTreeItemToACMap[laneItem] = lane; // return Lane item return laneItem; } else { return nullptr; } } case SUMO_TAG_CROSSING: { // obtain Crossing GNECrossing* crossing = myFrameParent->getViewNet()->getNet()->retrieveCrossing(myAC->getID(), false); if(crossing) { // obtain junction GNEJunction* junction = crossing->getParentJunction(); // create junction item FXTreeItem* junctionItem = myTreelist->insertItem(nullptr, nullptr, junction->getHierarchyName().c_str(), junction->getIcon(), junction->getIcon()); junctionItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionItem] = junction; // return junction Item return junctionItem; } else { return nullptr; } } case SUMO_TAG_CONNECTION: { // obtain Connection GNEConnection* connection = myFrameParent->getViewNet()->getNet()->retrieveConnection(myAC->getID(), false); if(connection) { // create edge from item FXTreeItem* edgeFromItem = myTreelist->insertItem(nullptr, nullptr, connection->getEdgeFrom()->getHierarchyName().c_str(), connection->getEdgeFrom()->getIcon(), connection->getEdgeFrom()->getIcon()); edgeFromItem->setExpanded(true); // create edge to item FXTreeItem* edgeToItem = myTreelist->insertItem(nullptr, nullptr, connection->getEdgeTo()->getHierarchyName().c_str(), connection->getEdgeTo()->getIcon(), connection->getEdgeTo()->getIcon()); edgeToItem->setExpanded(true); // create connection item FXTreeItem* connectionItem = myTreelist->insertItem(0, edgeToItem, connection->getHierarchyName().c_str(), connection->getIcon(), connection->getIcon()); connectionItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[edgeFromItem] = connection->getEdgeFrom(); myTreeItemToACMap[edgeToItem] = connection->getEdgeTo(); myTreeItemToACMap[connectionItem] = connection; // return connection item return connectionItem; } else { return nullptr; } } default: { // obtain tag property (only for improve code legibility) const auto &tagValue = GNEAttributeCarrier::getTagProperties(myAC->getTag()); // check if is an additional, and in other case return nullptr if(tagValue.isAdditional()) { // Obtain Additional GNEAdditional* additional = myFrameParent->getViewNet()->getNet()->retrieveAdditional(myAC->getTag(), myAC->getID(), false); if(additional) { // first check if additional has another additional as parent (to add it into root) if (tagValue.hasParent()) { GNEAdditional* additionalParent = myFrameParent->getViewNet()->getNet()->retrieveAdditional(tagValue.getParentTag(), additional->getAttribute(GNE_ATTR_PARENT)); // create additional parent item FXTreeItem* additionalParentItem = myTreelist->insertItem(0, 0, additionalParent->getHierarchyName().c_str(), additionalParent->getIcon(), additionalParent->getIcon()); additionalParentItem->setExpanded(true); // Save it in myTreeItemToACMap myTreeItemToACMap[additionalParentItem] = additionalParent; } if(tagValue.hasAttribute(SUMO_ATTR_EDGE)) { // obtain edge parent GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(additional->getAttribute(SUMO_ATTR_EDGE)); //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions) FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " origin").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " destiny").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); junctionDestinyItem->setExpanded(true); // Create edge item FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon()); edgeItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionSourceItem] = edge->getGNEJunctionSource(); myTreeItemToACMap[junctionDestinyItem] = edge->getGNEJunctionDestiny(); myTreeItemToACMap[edgeItem] = edge; // return edge item return edgeItem; } else if (tagValue.hasAttribute(SUMO_ATTR_LANE)) { // obtain lane parent GNELane* lane = myFrameParent->getViewNet()->getNet()->retrieveLane(additional->getAttribute(SUMO_ATTR_LANE)); // obtain edge parent GNEEdge* edge = myFrameParent->getViewNet()->getNet()->retrieveEdge(lane->getParentEdge().getID()); //inser Junctions of lane of edge in tree (Pararell because a edge has always two Junctions) FXTreeItem* junctionSourceItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " origin").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); FXTreeItem* junctionDestinyItem = myTreelist->insertItem(nullptr, nullptr, (edge->getGNEJunctionSource()->getHierarchyName() + " destiny").c_str(), edge->getGNEJunctionSource()->getIcon(), edge->getGNEJunctionSource()->getIcon()); junctionDestinyItem->setExpanded(true); // Create edge item FXTreeItem* edgeItem = myTreelist->insertItem(nullptr, junctionDestinyItem, edge->getHierarchyName().c_str(), edge->getIcon(), edge->getIcon()); edgeItem->setExpanded(true); // Create lane item FXTreeItem* laneItem = myTreelist->insertItem(0, edgeItem, lane->getHierarchyName().c_str(), lane->getIcon(), lane->getIcon()); laneItem->setExpanded(true); // Save items in myTreeItemToACMap myTreeItemToACMap[junctionSourceItem] = edge->getGNEJunctionSource(); myTreeItemToACMap[junctionDestinyItem] = edge->getGNEJunctionDestiny(); myTreeItemToACMap[edgeItem] = edge; myTreeItemToACMap[laneItem] = lane; // return lane item return laneItem; } } } return nullptr; } } }
void GNEDeleteFrame::removeAttributeCarrier(GNEAttributeCarrier* ac, bool ignoreOptions) { // obtain clicked position Position clickedPosition = myViewNet->getPositionInformation(); if (myDeleteOptions->deleteOnlyGeometryPoints() && !ignoreOptions) { // check type of of GL object switch (ac->getTag()) { case SUMO_TAG_EDGE: { GNEEdge* edge = dynamic_cast<GNEEdge*>(ac); assert(edge); if (edge->getVertexIndex(clickedPosition, false) != -1) { edge->deleteGeometryPoint(clickedPosition); } break; } case SUMO_TAG_POLY: { GNEPoly* polygon = dynamic_cast<GNEPoly*>(ac); assert(polygon); if (polygon->getVertexIndex(clickedPosition, false) != -1) { polygon->deleteGeometryPoint(clickedPosition); } break; } default: { break; } } } else { // check type of of GL object switch (ac->getTag()) { case SUMO_TAG_JUNCTION: { GNEJunction* junction = dynamic_cast<GNEJunction*>(ac); assert(junction); // obtain number of additionals of junction's childs int numberOfAdditionals = 0; for (auto i : junction->getGNEEdges()) { numberOfAdditionals += (int)i->getAdditionalChilds().size(); for (auto j : i->getLanes()) { UNUSED_PARAMETER(j); numberOfAdditionals += (int)i->getAdditionalChilds().size(); } } // Check if junction can be deleted if (myDeleteOptions->forceDeleteAdditionals() || ignoreOptions) { myViewNet->getNet()->deleteJunction(junction, myViewNet->getUndoList()); } else { if (numberOfAdditionals > 0) { // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Opening FXMessageBox 'Force deletion needed'"); } std::string plural = numberOfAdditionals > 1 ? "s" : ""; // Open warning DialogBox FXMessageBox::warning(getViewNet()->getApp(), MBOX_OK, ("Problem deleting " + toString(junction->getTag())).c_str(), "%s", (toString(junction->getTag()) + " '" + junction->getID() + "' cannot be deleted because owns " + toString(numberOfAdditionals) + " additional child" + plural + ".\n Check 'Force deletion of additionals' to force deletion.").c_str()); // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Closed FXMessageBox 'Force deletion needed' with 'OK'"); } } else { myViewNet->getNet()->deleteJunction(junction, myViewNet->getUndoList()); } } break; } case SUMO_TAG_EDGE: { GNEEdge* edge = dynamic_cast<GNEEdge*>(ac); assert(edge); // check if click was over a geometry point or over a shape's edge if (edge->getVertexIndex(clickedPosition, false) != -1) { edge->deleteGeometryPoint(clickedPosition); } else { int numberOfAdditionalChilds = (int)edge->getAdditionalChilds().size(); int numberOfAdditionalParents = (int)edge->getAdditionalParents().size(); // Iterate over lanes and obtain total number of additional childs for (auto i : edge->getLanes()) { numberOfAdditionalChilds += (int)i->getAdditionalChilds().size(); } // Check if edge can be deleted if (myDeleteOptions->forceDeleteAdditionals() || ignoreOptions) { // when deleting a single edge, keep all unaffected connections as they were myViewNet->getNet()->deleteEdge(edge, myViewNet->getUndoList(), false); } else { if (numberOfAdditionalChilds > 0) { // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Opening FXMessageBox 'Force deletion needed'"); } std::string plural = numberOfAdditionalChilds > 1 ? "s" : ""; // Open warning DialogBox FXMessageBox::warning(getViewNet()->getApp(), MBOX_OK, ("Problem deleting " + toString(edge->getTag())).c_str(), "%s", (toString(edge->getTag()) + " '" + edge->getID() + "' cannot be deleted because owns " + toString(numberOfAdditionalChilds) + " additional" + plural + ".\n Check 'Force deletion of additionals' to force deletion.").c_str()); // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Closed FXMessageBox 'Force deletion needed' with 'OK'"); } } else if (numberOfAdditionalParents > 0) { // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Opening FXMessageBox 'Force deletion needed'"); } std::string plural = numberOfAdditionalParents > 1 ? "s" : ""; // Open warning DialogBox FXMessageBox::warning(getViewNet()->getApp(), MBOX_OK, ("Problem deleting " + toString(edge->getTag())).c_str(), "%s", (toString(edge->getTag()) + " '" + edge->getID() + "' cannot be deleted because is part of " + toString(numberOfAdditionalParents) + " additional" + plural + ".\n Check 'Force deletion of additionals' to force deletion.").c_str()); // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Closed FXMessageBox 'Force deletion needed' with 'OK'"); } } else { // when deleting a single edge, keep all unaffected connections as they were myViewNet->getNet()->deleteEdge(edge, myViewNet->getUndoList(), false); } } } break; } case SUMO_TAG_LANE: { GNELane* lane = dynamic_cast<GNELane*>(ac); assert(lane); // Check if lane can be deleted if (myDeleteOptions->forceDeleteAdditionals() || ignoreOptions) { // when deleting a single lane, keep all unaffected connections as they were myViewNet->getNet()->deleteLane(lane, myViewNet->getUndoList(), false); } else { if (lane->getAdditionalChilds().size() == 0) { // when deleting a single lane, keep all unaffected connections as they were myViewNet->getNet()->deleteLane(lane, myViewNet->getUndoList(), false); } else { // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Opening FXMessageBox 'Force deletion needed'"); } // open warning box FXMessageBox::warning(getViewNet()->getApp(), MBOX_OK, ("Problem deleting " + toString(lane->getTag())).c_str(), "%s", (toString(lane->getTag()) + " '" + lane->getID() + "' cannot be deleted because it has " + toString(lane->getAdditionalChilds().size()) + " additional childs.\n Check 'Force deletion of Additionals' to force deletion.").c_str()); // write warning if netedit is running in testing mode if (OptionsCont::getOptions().getBool("gui-testing-debug")) { WRITE_WARNING("Closed FXMessageBox 'Force deletion needed' with 'OK'"); } } } break; } case SUMO_TAG_CROSSING: { GNECrossing* crossing = dynamic_cast<GNECrossing*>(ac); assert(crossing); myViewNet->getNet()->deleteCrossing(crossing, myViewNet->getUndoList()); break; } case SUMO_TAG_CONNECTION: { GNEConnection* connection = dynamic_cast<GNEConnection*>(ac); assert(connection); myViewNet->getNet()->deleteConnection(connection, myViewNet->getUndoList()); break; } default: { // obtain tag property (only for improve code legibility) const auto &tagValue = GNEAttributeCarrier::getTagProperties(ac->getTag()); if(tagValue.isAdditional()) { GNEAdditional* additional = dynamic_cast<GNEAdditional*>(ac); assert(additional); myViewNet->getViewParent()->getAdditionalFrame()->removeAdditional(additional); } else if(tagValue.isShape()) { GNEShape* shape = dynamic_cast<GNEShape*>(ac); assert(shape); myViewNet->getNet()->deleteShape(shape, myViewNet->getUndoList()); } break; } } } // update view to show changes myViewNet->update(); }