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; }
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; } } }
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; }
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(); }
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(); }
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; }
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); } }
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 }
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(); }
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(); } }
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; }
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; }
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; }
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; }
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(); }
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(); }
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(); } }
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(); }
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(); }