Skip to content

Commit

Permalink
adding lanes now preserves connections and signal plans. refs #3742
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed Jan 4, 2018
1 parent db2f233 commit c25c9f1
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 61 deletions.
6 changes: 3 additions & 3 deletions src/netbuild/NBConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ NBConnection::getToLane() const {


void
NBConnection::shiftLaneIndex(NBEdge* edge, int offset) {
if (myFrom == edge) {
NBConnection::shiftLaneIndex(NBEdge* edge, int offset, int threshold) {
if (myFrom == edge && myFromLane > threshold) {
myFromLane += offset;
} else if (myTo == edge) {
} else if (myTo == edge && myToLane > threshold) {
myToLane += offset;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/netbuild/NBConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ class NBConnection {
/// @brief replaces the to-edge by the one given
bool replaceTo(NBEdge* which, int whichLane, NBEdge* by, int byLane);

/// @brief patches lane indices refering to the given edge
void shiftLaneIndex(NBEdge* edge, int offset);
/** @brief patches lane indices refering to the given edge and above the
* threshold by the given offset */
void shiftLaneIndex(NBEdge* edge, int offset, int threshold=-1);

/// @brief checks whether the edges are still valid
bool check(const NBEdgeCont& ec);
Expand Down
42 changes: 38 additions & 4 deletions src/netbuild/NBEdge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2810,7 +2810,7 @@ NBEdge::isNearEnough2BeJoined2(NBEdge* e, double threshold) const {


void
NBEdge::addLane(int index, bool recomputeShape, bool recomputeConnections) {
NBEdge::addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices) {
assert(index <= (int)myLanes.size());
myLanes.insert(myLanes.begin() + index, Lane(this, ""));
// copy attributes
Expand All @@ -2832,6 +2832,23 @@ NBEdge::addLane(int index, bool recomputeShape, bool recomputeConnections) {
(*i)->invalidateConnections(true);
}
invalidateConnections(true);
} else if (shiftIndices) {
// shift outgoing connections above the added lane to the left
for (Connection& c : myConnections) {
if (c.fromLane >= index) {
c.fromLane += 1;
}
}
// shift incoming connections above the added lane to the left
for (NBEdge* inc : myFrom->getIncomingEdges()) {
for (Connection& c : inc->myConnections) {
if (c.toLane >= index) {
c.toLane += 1;
}
}
}
myFrom->shiftTLConnectionLaneIndex(this, +1, index-1);
myTo->shiftTLConnectionLaneIndex(this, +1, index-1);
}
}

Expand All @@ -2841,13 +2858,13 @@ NBEdge::incLaneNo(int by) {
while ((int)myLanes.size() < newLaneNo) {
// recompute shapes on last addition
const bool recompute = ((int)myLanes.size() == newLaneNo - 1) && myStep < LANES2LANES_USER;
addLane((int)myLanes.size(), recompute, recompute);
addLane((int)myLanes.size(), recompute, recompute, false);
}
}


void
NBEdge::deleteLane(int index, bool recompute) {
NBEdge::deleteLane(int index, bool recompute, bool shiftIndices) {
assert(index < (int)myLanes.size());
myLanes.erase(myLanes.begin() + index);
if (recompute) {
Expand All @@ -2857,6 +2874,23 @@ NBEdge::deleteLane(int index, bool recompute) {
(*i)->invalidateConnections(true);
}
invalidateConnections(true);
} else if (shiftIndices) {
// shift outgoing connections above the delete lane to the right
for (Connection& c : myConnections) {
if (c.fromLane > index) {
c.fromLane -= 1;
}
}
// shift incoming connections above the delete lane to the right
for (NBEdge* inc : myFrom->getIncomingEdges()) {
for (Connection& c : inc->myConnections) {
if (c.toLane > index) {
c.toLane -= 1;
}
}
}
myFrom->shiftTLConnectionLaneIndex(this, -1, index);
myTo->shiftTLConnectionLaneIndex(this, -1, index);
}
}

Expand All @@ -2868,7 +2902,7 @@ NBEdge::decLaneNo(int by) {
while ((int)myLanes.size() > newLaneNo) {
// recompute shapes on last removal
const bool recompute = (int)myLanes.size() == newLaneNo + 1 && myStep < LANES2LANES_USER;
deleteLane((int)myLanes.size() - 1, recompute);
deleteLane((int)myLanes.size() - 1, recompute, false);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/netbuild/NBEdge.h
Original file line number Diff line number Diff line change
Expand Up @@ -1114,10 +1114,10 @@ class NBEdge : public Named, public Parameterised {
void decLaneNo(int by);

/// @brief delete lane
void deleteLane(int index, bool recompute = true);
void deleteLane(int index, bool recompute, bool shiftIndices);

/// @brief add lane
void addLane(int index, bool recomputeShape, bool recomputeConnections);
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices);

/// @brief mark edge as in lane to state lane
void markAsInLane2LaneState();
Expand Down
4 changes: 2 additions & 2 deletions src/netbuild/NBLoadedSUMOTLDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,13 @@ NBLoadedSUMOTLDef::collectLinks() {

/// @brief patches signal plans by modifying lane indices
void
NBLoadedSUMOTLDef::shiftTLConnectionLaneIndex(NBEdge* edge, int offset) {
NBLoadedSUMOTLDef::shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold) {
// avoid shifting twice if the edge is incoming and outgoing to a joined TLS
if (myShifted.count(edge) == 0) {
/// XXX what if an edge should really be shifted twice?
myShifted.insert(edge);
for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
(*it).shiftLaneIndex(edge, offset);
(*it).shiftLaneIndex(edge, offset, threshold);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/netbuild/NBLoadedSUMOTLDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ class NBLoadedSUMOTLDef : public NBTrafficLightDefinition {
void replaceRemoved(NBEdge* removed, int removedLane,
NBEdge* by, int byLane);

/// @brief patches signal plans by modifying lane indices
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset);
/** @brief patches signal plans by modifying lane indices
* with the given offset, only indices with a value above threshold are modified
*/
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold=-1);

/** @brief Adds a phase to the logic
* the new phase is inserted at the end of the list of already added phases
Expand Down
4 changes: 2 additions & 2 deletions src/netbuild/NBNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,9 @@ NBNode::invalidateTLS(NBTrafficLightLogicCont& tlCont, bool removedConnections,


void
NBNode::shiftTLConnectionLaneIndex(NBEdge* edge, int offset) {
NBNode::shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold) {
for (std::set<NBTrafficLightDefinition*>::iterator it = myTrafficLights.begin(); it != myTrafficLights.end(); ++it) {
(*it)->shiftTLConnectionLaneIndex(edge, offset);
(*it)->shiftTLConnectionLaneIndex(edge, offset, threshold);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/netbuild/NBNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ class NBNode : public Named, public Parameterised {
/// @brief causes the traffic light to be computed anew
void invalidateTLS(NBTrafficLightLogicCont& tlCont, bool removedConnections, bool addedConnections);

/// @brief patches loaded signal plans by modifying lane indices
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset);
/// @brief patches loaded signal plans by modifying lane indices above threshold by the given offset
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold=-1);
/// @}


Expand Down
3 changes: 2 additions & 1 deletion src/netbuild/NBTrafficLightDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,10 @@ class NBTrafficLightDefinition : public Named, public Parameterised {
NBEdge* by, int byLane) = 0;

/// @brief patches (loaded) signal plans by modifying lane indices
virtual void shiftTLConnectionLaneIndex(NBEdge* edge, int offset) {
virtual void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold=-1) {
UNUSED_PARAMETER(edge);
UNUSED_PARAMETER(offset);
UNUSED_PARAMETER(threshold);
}

/** @brief Returns the list of incoming edges (must be build first)
Expand Down
13 changes: 7 additions & 6 deletions src/netedit/GNEChange_Lane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ FXIMPLEMENT_ABSTRACT(GNEChange_Lane, GNEChange, NULL, 0)


/// @brief constructor for creating an edge
GNEChange_Lane::GNEChange_Lane(GNEEdge* edge, GNELane* lane, const NBEdge::Lane& laneAttrs, bool forward):
GNEChange_Lane::GNEChange_Lane(GNEEdge* edge, GNELane* lane, const NBEdge::Lane& laneAttrs, bool forward, bool recomputeConnections):
GNEChange(edge->getNet(), forward),
myEdge(edge),
myLane(lane),
myLaneAttrs(laneAttrs) {
myLaneAttrs(laneAttrs),
myRecomputeConnections(recomputeConnections)
{
assert(myNet);
myEdge->incRef("GNEChange_Lane");
if (myLane) {
Expand Down Expand Up @@ -102,7 +104,7 @@ GNEChange_Lane::undo() {
}
}
// remove lane from edge
myEdge->removeLane(myLane);
myEdge->removeLane(myLane, false);
// Remove additionals vinculated with this lane
for (auto i : myAdditionalChilds) {
myNet->deleteAdditional(i);
Expand Down Expand Up @@ -147,8 +149,7 @@ GNEChange_Lane::redo() {
}
}
// add lane and their attributes to edge
// new lane, true: connections should be recomputed (XXX toogle with a new option)
myEdge->addLane(myLane, myLaneAttrs, true);
myEdge->addLane(myLane, myLaneAttrs, myRecomputeConnections);
// add additional vinculated with this lane of net
for (auto i : myAdditionalChilds) {
myNet->insertAdditional(i);
Expand All @@ -167,7 +168,7 @@ GNEChange_Lane::redo() {
}
}
// remove lane from edge
myEdge->removeLane(myLane);
myEdge->removeLane(myLane, myRecomputeConnections);
// Remove additional vinculated with this lane of net
for (auto i : myAdditionalChilds) {
myNet->deleteAdditional(i);
Expand Down
6 changes: 5 additions & 1 deletion src/netedit/GNEChange_Lane.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ class GNEChange_Lane : public GNEChange {
* @param[in] lane The lane to be deleted or 0 if a lane should be created
* @param[in] laneAttrs The attributes of the lane to be created/deleted
* @param[in] forward Whether to create/delete (true/false)
* @param[in] recomputeConnections Whether to recompute all connections for the affected edge
*/
GNEChange_Lane(GNEEdge* edge, GNELane* lane, const NBEdge::Lane& laneAttrs, bool forward);
GNEChange_Lane(GNEEdge* edge, GNELane* lane, const NBEdge::Lane& laneAttrs, bool forward, bool recomputeConnections=true);

/// @brief Destructor
~GNEChange_Lane();
Expand Down Expand Up @@ -98,6 +99,9 @@ class GNEChange_Lane : public GNEChange {

/// @brief we need to preserve the list of additional sets in which this lane is a child
std::vector<GNEAdditional*> myAdditionalParents;

/// @bried whether to recompute connection when adding a new lane
bool myRecomputeConnections;
};

#endif
Expand Down
12 changes: 8 additions & 4 deletions src/netedit/GNEDeleteFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ GNEDeleteFrame::removeAttributeCarrier(GNEAttributeCarrier* ac) {
}
// Check if edge can be deleted
if (myAutomaticallyDeleteAdditionalsCheckButton->getCheck()) {
myViewNet->getNet()->deleteEdge(edge, myViewNet->getUndoList());
// 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
Expand Down Expand Up @@ -452,7 +453,8 @@ GNEDeleteFrame::removeAttributeCarrier(GNEAttributeCarrier* ac) {
WRITE_WARNING("Closed FXMessageBox 'Force deletion needed' with 'OK'");
}
} else {
myViewNet->getNet()->deleteEdge(edge, myViewNet->getUndoList());
// when deleting a single edge, keep all unaffected connections as they were
myViewNet->getNet()->deleteEdge(edge, myViewNet->getUndoList(), false);
}
}
}
Expand All @@ -462,10 +464,12 @@ GNEDeleteFrame::removeAttributeCarrier(GNEAttributeCarrier* ac) {
GNELane* lane = dynamic_cast<GNELane*>(ac);
// Check if lane can be deleted
if (myAutomaticallyDeleteAdditionalsCheckButton->getCheck()) {
myViewNet->getNet()->deleteLane(lane, myViewNet->getUndoList());
// 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) {
myViewNet->getNet()->deleteLane(lane, myViewNet->getUndoList());
// 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")) {
Expand Down
8 changes: 5 additions & 3 deletions src/netedit/GNEEdge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,8 @@ void
GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeConnections) {
const int index = lane ? lane->getIndex() : myNBEdge.getNumLanes();
// the laneStruct must be created first to ensure we have some geometry
myNBEdge.addLane(index, true, recomputeConnections);
// unless the connections are fully recomputed, existing indices must be shifted
myNBEdge.addLane(index, true, recomputeConnections, !recomputeConnections);
if (lane) {
// restore a previously deleted lane
myLanes.insert(myLanes.begin() + index, lane);
Expand Down Expand Up @@ -1120,15 +1121,16 @@ GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeCon


void
GNEEdge::removeLane(GNELane* lane) {
GNEEdge::removeLane(GNELane* lane, bool recomputeConnections) {
if (myLanes.size() == 0) {
throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + toString(getTag()));
}
if (lane == 0) {
lane = myLanes.back();
}
// Delete lane of edge's container
myNBEdge.deleteLane(lane->getIndex(), false);
// unless the connections are fully recomputed, existing indices must be shifted
myNBEdge.deleteLane(lane->getIndex(), recomputeConnections, !recomputeConnections);
lane->decRef("GNEEdge::removeLane");
myLanes.erase(myLanes.begin() + lane->getIndex());
// Delete lane if is unreferenced
Expand Down
2 changes: 1 addition & 1 deletion src/netedit/GNEEdge.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class GNEEdge : public GNENetElement {
void addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeConnections);

/// @briefdecrease the number of lanes by one. argument is only used to increase robustness (assertions)
void removeLane(GNELane* lane);
void removeLane(GNELane* lane, bool recomputeConnections);

/// @brief adds a connection
void addConnection(NBEdge::Connection nbCon, bool selectAfterCreation = false);
Expand Down
Loading

0 comments on commit c25c9f1

Please sign in to comment.