long
GNEConnectorFrame::onCmdSelectConflicts(FXObject*, FXSelector, void*) {
    std::vector<GUIGlID> selectIDs;
    // conflicts happen per edge so we can look at each edge in isolation
    const std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges();
    for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) {
        NBEdge* nbe = (*edge_it)->getNBEdge();
        const EdgeVector destinations = nbe->getConnectedEdges();
        const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
        for (EdgeVector::const_iterator dest_it = destinations.begin(); dest_it != destinations.end(); dest_it++) {
            GNEEdge* dest = myViewNet->getNet()->retrieveEdge((*dest_it)->getID());
            const GNEEdge::LaneVector& destLanes = dest->getLanes();
            for (GNEEdge::LaneVector::const_iterator it_lane = destLanes.begin(); it_lane != destLanes.end(); it_lane++) {
                const bool isConflicted = count_if(
                                              connections.begin(), connections.end(),
                                              NBEdge::connections_toedgelane_finder(*dest_it, (int)(*it_lane)->getIndex(), -1)) > 1;
                if (isConflicted) {
                    selectIDs.push_back((*it_lane)->getGlID());
                }
            }
        }

    }
    myViewNet->getViewParent()->getSelectorFrame()->handleIDs(selectIDs, false, GNESelectorFrame::SET_REPLACE);
    return 1;
}
Exemple #2
0
void
GNENet::moveSelection(const Position& moveSrc, const Position& moveDest) {
    Position delta = moveDest - moveSrc;
    // move junctions
    std::set<GNEJunction*> junctionSet;
    std::vector<GNEJunction*> junctions = retrieveJunctions(true);
    for (std::vector<GNEJunction*>::iterator it = junctions.begin(); it != junctions.end(); it++) {
        Position newPos = (*it)->getNBNode()->getPosition() + delta;
        (*it)->move(newPos);
        junctionSet.insert(*it);
    }

    // move edge geometry (endpoints are already moved)
    std::vector<GNEEdge*> edges = retrieveEdges(true);
    for (std::vector<GNEEdge*>::iterator it = edges.begin(); it != edges.end(); it++) {
        GNEEdge* edge = *it;
        if (edge) {
            if (junctionSet.count(edge->getSource()) > 0 &&
                    junctionSet.count(edge->getDest()) > 0) {
                // edge and its endpoints are selected, move all the inner points as well
                edge->moveGeometry(delta);
            } else {
                // move only geometry near mouse
                edge->moveGeometry(moveSrc, delta, true);
            }
        }
    }
}
void
GNEConnectorFrame::initTargets() {
    // gather potential targets
    NBNode* nbn = myCurrentLane->getParentEdge().getGNEJunctionDestiny()->getNBNode();

    const EdgeVector& outgoing = nbn->getOutgoingEdges();
    for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
        GNEEdge* edge = myViewNet->getNet()->retrieveEdge((*it)->getID());
        const GNEEdge::LaneVector& lanes = edge->getLanes();
        for (GNEEdge::LaneVector::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); it_lane++) {
            myPotentialTargets.insert(*it_lane);
        }
    }
    // set color for existing connections
    const int fromIndex = myCurrentLane->getIndex();
    NBEdge* srcEdge = myCurrentLane->getParentEdge().getNBEdge();
    std::vector<NBEdge::Connection> connections = srcEdge->getConnectionsFromLane(fromIndex);
    for (std::set<GNELane*>::iterator it = myPotentialTargets.begin(); it != myPotentialTargets.end(); it++) {
        switch (getLaneStatus(connections, *it)) {
            case CONNECTED:
                (*it)->setSpecialColor(&targetColor);
                break;
            case CONNECTED_PASS:
                (*it)->setSpecialColor(&targetPassColor);
                break;
            case CONFLICTED:
                (*it)->setSpecialColor(&conflictColor);
                break;
            case UNCONNECTED:
                (*it)->setSpecialColor(&potentialTargetColor);
                break;
        }
    }
}
Exemple #4
0
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;
}
Exemple #5
0
GNELane::GNELane(GNEEdge& edge, const int index) :
    GNENetElement(edge.getNet(), edge.getNBEdge()->getLaneID(index), GLO_LANE, SUMO_TAG_LANE),
    myParentEdge(edge),
    myIndex(index),
    mySpecialColor(0),
    myTLSEditor(0) {
    updateGeometry();
}
Exemple #6
0
void
GNENet::reverseEdge(GNEEdge* edge, GNEUndoList* undoList) {
    undoList->p_begin("reverse edge");
    deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
    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);
    undoList->p_end();
}
Exemple #7
0
void
GNENet::duplicateLane(GNELane* lane, GNEUndoList* undoList) {
    undoList->p_begin("duplicate lane");
    GNEEdge* edge = &lane->getParentEdge();
    const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
    GNELane* newLane = new GNELane(*edge, lane->getIndex());
    undoList->add(new GNEChange_Lane(edge, newLane, laneAttrs, true), true);
    requireRecompute();
    undoList->p_end();
}
long
GNEInspectorFrame::onCmdCopyTemplate(FXObject*, FXSelector, void*) {
    for (std::vector<GNEAttributeCarrier*>::iterator it = myACs.begin(); it != myACs.end(); it++) {
        GNEEdge* edge = dynamic_cast<GNEEdge*>(*it);
        assert(edge);
        edge->copyTemplate(myEdgeTemplate, myViewNet->getUndoList());
        inspect(myACs);
    }
    return 1;
}
bool
GNEDemandElement::isRouteValid(const std::vector<GNEEdge*>& edges, bool report) {
    if (edges.size() == 0) {
        // routes cannot be empty
        return false;
    } else if (edges.size() == 1) {
        // routes with a single edge are valid
        return true;
    } else {
        // iterate over edges to check that compounds a chain
        auto it = edges.begin();
        while (it != edges.end() - 1) {
            GNEEdge* currentEdge = *it;
            GNEEdge* nextEdge = *(it + 1);
            // consecutive edges aren't allowed
            if (currentEdge->getID() == nextEdge->getID()) {
                return false;
            }
            // make sure that edges are consecutives
            if (std::find(currentEdge->getGNEJunctionDestiny()->getGNEOutgoingEdges().begin(),
                          currentEdge->getGNEJunctionDestiny()->getGNEOutgoingEdges().end(),
                          nextEdge) == currentEdge->getGNEJunctionDestiny()->getGNEOutgoingEdges().end()) {
                if (report) {
                    WRITE_WARNING("Parameter 'Route' invalid. " + currentEdge->getTagStr() + " '" + currentEdge->getID() +
                                  "' ins't consecutive to " + nextEdge->getTagStr() + " '" + nextEdge->getID() + "'");
                }
                return false;
            }
            it++;
        }
    }
    return true;
}
Exemple #10
0
void
GNEJunction::move(Position pos) {
    const Position orig = myNBNode.getPosition();
    setPosition(pos);
    myNet->refreshElement(this);
    const EdgeVector& incident = getNBNode()->getEdges();
    for (EdgeVector::const_iterator it = incident.begin(); it != incident.end(); it++) {
        GNEEdge* edge = myNet->retrieveEdge((*it)->getID());
        edge->updateJunctionPosition(this, orig);
    }
}
Exemple #11
0
void
GNENet::remapEdge(GNEEdge* oldEdge, GNEJunction* from, GNEJunction* to, GNEUndoList* undoList, bool keepEndpoints) {
    deleteEdge(oldEdge, undoList); // delete first so we can reuse the name, reference stays valid
    if (from != to) {
        GNEEdge* newEdge = createEdge(from, to, oldEdge, undoList, oldEdge->getMicrosimID(), false, true);
        newEdge->setAttribute(SUMO_ATTR_SHAPE, oldEdge->getAttribute(SUMO_ATTR_SHAPE), undoList);
        if (keepEndpoints) {
            newEdge->setAttribute(GNE_ATTR_SHAPE_START, oldEdge->getAttribute(GNE_ATTR_SHAPE_START), undoList);
            newEdge->setAttribute(GNE_ATTR_SHAPE_END, oldEdge->getAttribute(GNE_ATTR_SHAPE_END), undoList);
        }
    }
    // @todo remap connectivity as well
}
Exemple #12
0
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();
}
Exemple #13
0
void
GNENet::deleteLane(GNELane* lane, GNEUndoList* undoList) {
    GNEEdge* edge = &lane->getParentEdge();
    if (edge->getNBEdge()->getNumLanes() == 1) {
        // remove the whole edge instead
        deleteEdge(edge, undoList);
    } else {
        undoList->p_begin("delete lane");
        const NBEdge::Lane& laneAttrs = edge->getNBEdge()->getLaneStruct(lane->getIndex());
        const bool sidewalk = laneAttrs.permissions == SVC_PEDESTRIAN;
        undoList->add(new GNEChange_Lane(edge, lane, laneAttrs, false), true);
        if (gSelected.isSelected(GLO_LANE, lane->getGlID())) {
            std::set<GUIGlID> deselected;
            deselected.insert(lane->getGlID());
            undoList->add(new GNEChange_Selection(std::set<GUIGlID>(), deselected, true), true);
        }
        if (sidewalk) {
            edge->getSource()->removeFromCrossings(edge, undoList);
            edge->getDest()->removeFromCrossings(edge, undoList);
            edge->getSource()->setLogicValid(false, undoList);
            edge->getDest()->setLogicValid(false, undoList);
        }
        requireRecompute();
        undoList->p_end();
    }
}
Exemple #14
0
long
GNEConnectorFrame::onCmdSelectPass(FXObject*, FXSelector, void*) {
    std::vector<GUIGlID> selectIDs;
    const std::vector<GNEEdge*> edges = myViewNet->getNet()->retrieveEdges();
    for (std::vector<GNEEdge*>::const_iterator edge_it = edges.begin(); edge_it != edges.end(); edge_it++) {
        GNEEdge* edge = *edge_it;
        NBEdge* nbe = edge->getNBEdge();
        const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
        for (std::vector<NBEdge::Connection>::const_iterator it = connections.begin(); it != connections.end(); ++it) {
            if (it->mayDefinitelyPass) {
                GNELane* lane = edge->getLanes()[it->fromLane];
                selectIDs.push_back(lane->getGlID());
            }
        }
    }
    myViewNet->getViewParent()->getSelectorFrame()->handleIDs(selectIDs, false, GNESelectorFrame::SET_REPLACE);
    return 1;
}
Exemple #15
0
GNEJunction*
GNENet::splitEdge(GNEEdge* edge, const Position& pos, GNEUndoList* undoList, GNEJunction* newJunction) {
    undoList->p_begin("split edge");
    deleteEdge(edge, undoList); // still exists. we delete it so we can reuse the name in case of resplit
    // compute geometry
    const PositionVector& oldGeom = edge->getNBEdge()->getGeometry();
    const SUMOReal linePos = oldGeom.nearest_offset_to_point2D(pos, false);
    std::pair<PositionVector, PositionVector> newGeoms = oldGeom.splitAt(linePos);
    // figure out the new name
    int posBase = 0;
    std::string baseName = edge->getMicrosimID();
    if (edge->wasSplit()) {
        size_t sep_index = baseName.rfind('.');
        if (sep_index != std::string::npos) { // edge may have been renamed in between
            std::string posString = baseName.substr(sep_index + 1);
            try {
                posBase = TplConvert::_2int(posString.c_str());
                baseName = baseName.substr(0, sep_index); // includes the .
            } catch (NumberFormatException) {
            }
        }
    }
    baseName += '.';
    // create edges
    if (newJunction == 0) {
        newJunction = createJunction(pos, undoList);
    }
    GNEEdge* firstPart = createEdge(edge->getSource(), newJunction, edge,
                                    undoList, baseName + toString(posBase), true);
    GNEEdge* secondPart = createEdge(newJunction, edge->getDest(), edge,
                                     undoList, baseName + toString(posBase + (int)linePos), true);
    // fix geometry
    firstPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.first[0]), undoList);
    firstPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.first[-1]), undoList);
    newGeoms.first.pop_back();
    newGeoms.first.erase(newGeoms.first.begin());
    firstPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.first), undoList);

    secondPart->setAttribute(GNE_ATTR_SHAPE_START, toString(newGeoms.second[0]), undoList);
    secondPart->setAttribute(GNE_ATTR_SHAPE_END, toString(newGeoms.second[-1]), undoList);
    newGeoms.second.pop_back();
    newGeoms.second.erase(newGeoms.second.begin());
    secondPart->setAttribute(SUMO_ATTR_SHAPE, toString(newGeoms.second), undoList);
    // fix connections
    std::vector<NBEdge::Connection>& connections = edge->getNBEdge()->getConnections();
    for (std::vector<NBEdge::Connection>::iterator con_it = connections.begin(); con_it != connections.end(); con_it++) {
        undoList->add(new GNEChange_Connection(
                          secondPart, con_it->fromLane, con_it->toEdge->getID(), con_it->toLane, false, true), true);
    }
    undoList->p_end();
    return newJunction;
}
Exemple #16
0
bool
GNETLSEditorFrame::controlsEdge(GNEEdge& edge) const {
    if (myEditedDef != 0) {
        const NBConnectionVector& links = myEditedDef->getControlledLinks();
        for (NBConnectionVector::const_iterator it = links.begin(); it != links.end(); it++) {
            if ((*it).getFrom()->getID() == edge.getMicrosimID()) {
                return true;
            }
        }
    }
    return false;
}
Exemple #17
0
long
GNEConnectorFrame::onCmdSelectDeadStarts(FXObject*, FXSelector, void*) {
    GNENet* net = myViewNet->getNet();
    std::set<GUIGlID> selectIDs;
    // every edge knows only its outgoing connections so we look at whole junctions
    const std::vector<GNEJunction*> junctions = net->retrieveJunctions();
    for (std::vector<GNEJunction*>::const_iterator junction_it = junctions.begin(); junction_it != junctions.end(); junction_it++) {
        // first collect all outgoing lanes
        const EdgeVector& outgoing = (*junction_it)->getNBNode()->getOutgoingEdges();
        for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
            GNEEdge* edge = net->retrieveEdge((*it)->getID());
            const std::set<GUIGlID> laneIDs = edge->getLaneGlIDs();
            for (std::set<GUIGlID>::const_iterator lid_it = laneIDs.begin(); lid_it != laneIDs.end(); lid_it++) {
                selectIDs.insert(*lid_it);
            }
        }
        // then remove all approached lanes
        const EdgeVector& incoming = (*junction_it)->getNBNode()->getIncomingEdges();
        for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) {
            GNEEdge* edge = net->retrieveEdge((*it)->getID());
            NBEdge* nbe = edge->getNBEdge();
            const std::vector<NBEdge::Connection>& connections = nbe->getConnections();
            for (std::vector<NBEdge::Connection>::const_iterator con_it = connections.begin(); con_it != connections.end(); con_it++) {
                GNEEdge* approachedEdge = net->retrieveEdge(con_it->toEdge->getID());
                GNELane* approachedLane = approachedEdge->getLanes()[con_it->toLane];
                selectIDs.erase(approachedLane->getGlID());
            }
        }
    }
    myViewNet->getViewParent()->getSelectorFrame()->handleIDs(
        std::vector<GUIGlID>(selectIDs.begin(), selectIDs.end()),
        false, GNESelectorFrame::SET_REPLACE);
    return 1;
}
Exemple #18
0
void
GNENet::finishMoveSelection(GNEUndoList* undoList) {
    undoList->p_begin("move selection");
    // register moved junctions
    std::set<GNEJunction*> junctionSet;
    std::vector<GNEJunction*> junctions = retrieveJunctions(true);
    for (std::vector<GNEJunction*>::iterator it = junctions.begin(); it != junctions.end(); it++) {
        (*it)->registerMove(undoList);
        junctionSet.insert(*it);
    }

    // register moved edge geometry (endpoints are already moved)
    std::vector<GNEEdge*> edges = retrieveEdges(true);
    for (std::vector<GNEEdge*>::iterator it = edges.begin(); it != edges.end(); it++) {
        GNEEdge* edge = *it;
        if (edge) {
            const std::string& newShape = edge->getAttribute(SUMO_ATTR_SHAPE);
            edge->setAttribute(SUMO_ATTR_SHAPE, newShape, undoList);
        }
    }
    undoList->p_end();
}
Exemple #19
0
void
GNENet::mergeJunctions(GNEJunction* moved, GNEJunction* target, GNEUndoList* undoList) {
    undoList->p_begin("merge junctions");
    // position of moved and target are probably a bit different (snap radius)
    moved->move(target->getNBNode()->getPosition());
    // register the move with undolist (must happend within the undo group)
    moved->registerMove(undoList);
    // deleting edges changes in the underlying EdgeVector so we have to make a copy
    const EdgeVector incoming = moved->getNBNode()->getIncomingEdges();
    for (EdgeVector::const_iterator it = incoming.begin(); it != incoming.end(); it++) {
        GNEEdge* oldEdge = myEdges[(*it)->getID()];
        remapEdge(oldEdge, oldEdge->getSource(), target, undoList);
    }
    // deleting edges changes in the underlying EdgeVector so we have to make a copy
    const EdgeVector outgoing = moved->getNBNode()->getOutgoingEdges();
    for (EdgeVector::const_iterator it = outgoing.begin(); it != outgoing.end(); it++) {
        GNEEdge* oldEdge = myEdges[(*it)->getID()];
        remapEdge(oldEdge, target, oldEdge->getDest(), undoList);
    }
    deleteJunction(moved, undoList);
    undoList->p_end();
}
Exemple #20
0
void
GNECreateEdgeFrame::processClick(const Position& clickedPosition, GNEViewNetHelper::ObjectsUnderCursor& objectsUnderCursor, bool opossiteEdge, bool chainEdge) {
    if (!myViewNet->getUndoList()->hasCommandGroup()) {
        myViewNet->getUndoList()->p_begin("create new " + toString(SUMO_TAG_EDGE));
    }
    if (!objectsUnderCursor.getJunctionFront()) {
        objectsUnderCursor.setCreatedJunction(myViewNet->getNet()->createJunction(myViewNet->snapToActiveGrid(clickedPosition), myViewNet->getUndoList()));
    }
    if (myCreateEdgeSource == nullptr) {
        myCreateEdgeSource = objectsUnderCursor.getJunctionFront();
        myCreateEdgeSource->markAsCreateEdgeSource();
        update();
    } else {
        if (myCreateEdgeSource != objectsUnderCursor.getJunctionFront()) {
            // may fail to prevent double edges
            GNEEdge* newEdge = myViewNet->getNet()->createEdge(
                                   myCreateEdgeSource, objectsUnderCursor.getJunctionFront(), myViewNet->getViewParent()->getInspectorFrame()->getTemplateEditor()->getEdgeTemplate(), myViewNet->getUndoList());
            if (newEdge) {
                // create another edge, if create opposite edge is enabled
                if (opossiteEdge) {
                    myViewNet->getNet()->createEdge(objectsUnderCursor.getJunctionFront(), myCreateEdgeSource, myViewNet->getViewParent()->getInspectorFrame()->getTemplateEditor()->getEdgeTemplate(), myViewNet->getUndoList(), "-" + newEdge->getNBEdge()->getID());
                }
                myCreateEdgeSource->unMarkAsCreateEdgeSource();

                if (myViewNet->getUndoList()->hasCommandGroup()) {
                    myViewNet->getUndoList()->p_end();
                } else {
                    std::cout << "edge created without an open CommandGroup )-:\n";
                }
                if (chainEdge) {
                    myCreateEdgeSource = objectsUnderCursor.getJunctionFront();
                    myCreateEdgeSource->markAsCreateEdgeSource();
                    myViewNet->getUndoList()->p_begin("create new " + toString(SUMO_TAG_EDGE));
                } else {
                    myCreateEdgeSource = nullptr;
                }
            } else {
                myViewNet->setStatusBarText("An " + toString(SUMO_TAG_EDGE) + " with the same geometry already exists!");
            }
        } else {
            myViewNet->setStatusBarText("Start- and endpoint for an " + toString(SUMO_TAG_EDGE) + " must be distinct!");
        }
        update();
    }
}
Exemple #21
0
void
GNENet::replaceJunctionByGeometry(GNEJunction* junction, GNEUndoList* undoList) {
    undoList->p_begin("Replace junction by geometry");
    assert(junction->getNBNode()->checkIsRemovable());
    std::vector<std::pair<NBEdge*, NBEdge*> > toJoin = junction->getNBNode()->getEdgesToJoin();
    for (std::vector<std::pair<NBEdge*, NBEdge*> >::iterator j = toJoin.begin(); j != toJoin.end(); j++) {
        GNEEdge* begin = myEdges[(*j).first->getID()];
        GNEEdge* continuation = myEdges[(*j).second->getID()];
        deleteEdge(begin, undoList);
        deleteEdge(continuation, undoList);
        GNEEdge* newEdge = createEdge(begin->getSource(), continuation->getDest(), begin, undoList, begin->getMicrosimID(), false, true);
        PositionVector newShape = begin->getNBEdge()->getInnerGeometry();
        newShape.push_back(junction->getNBNode()->getPosition());
        newShape.append(continuation->getNBEdge()->getInnerGeometry());
        newEdge->setAttribute(SUMO_ATTR_SHAPE, toString(newShape), undoList);
        // @todo what about trafficlights at the end of oontinuation?
    }
    deleteJunction(junction, undoList);
    undoList->p_end();
}
Exemple #22
0
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;
        }
    }
}
Exemple #23
0
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;
        }
    }
}
Exemple #24
0
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();
}