Skip to content

Commit

Permalink
fix #1982
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed Feb 13, 2019
1 parent 17567f5 commit 8a2eb80
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 82 deletions.
6 changes: 5 additions & 1 deletion data/xsd/nodes_file.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@
</xsd:complexType>

<xsd:complexType name="joinType">
<xsd:attribute name="nodes" type="xsd:string" use="required"/>
<xsd:complexContent>
<xsd:extension base="nodeType">
<xsd:attribute name="nodes" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="joinExcludeType">
Expand Down
180 changes: 103 additions & 77 deletions src/netbuild/NBNodeCont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ NBNodeCont::addJoinExclusion(const std::vector<std::string>& ids, bool check) {


void
NBNodeCont::addCluster2Join(std::set<std::string> cluster) {
NBNodeCont::addCluster2Join(std::set<std::string> cluster, NBNode* node) {
// error handling has to take place here since joins could be loaded from multiple files
std::set<std::string> validCluster;
for (std::string nodeID : cluster) {
Expand Down Expand Up @@ -613,31 +613,31 @@ NBNodeCont::addCluster2Join(std::set<std::string> cluster) {
for (std::string nodeID : validCluster) {
myJoined.insert(nodeID);
}
myClusters2Join.push_back(validCluster);
myClusters2Join.push_back(std::make_pair(validCluster, node));
}


int
NBNodeCont::joinLoadedClusters(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) {
NodeClusters clusters;
for (std::vector<std::set<std::string> >::iterator it = myClusters2Join.begin(); it != myClusters2Join.end(); it++) {
int numJoined = 0;
for (auto& item : myClusters2Join) {
// verify loaded cluster
NodeSet cluster;
for (std::set<std::string>::iterator it_id = it->begin(); it_id != it->end(); it_id++) {
NBNode* node = retrieve(*it_id);
for (std::string nodeID : item.first) {
NBNode* node = retrieve(nodeID);
if (node == nullptr) {
WRITE_ERROR("unknown junction '" + *it_id + "' while joining");
WRITE_ERROR("unknown junction '" + nodeID + "' while joining");
} else {
cluster.insert(node);
}
}
if (cluster.size() > 1) {
clusters.push_back(cluster);
joinNodeCluster(cluster, dc, ec, tlc, item.second);
numJoined++;
}
}
joinNodeClusters(clusters, dc, ec, tlc);
myClusters2Join.clear(); // make save for recompute
return (int)clusters.size();
return numJoined;
}


Expand Down Expand Up @@ -1078,87 +1078,113 @@ NBNodeCont::shortestEdge(const NodeSet& cluster, const NodeSet& startNodes, cons
void
NBNodeCont::joinNodeClusters(NodeClusters clusters,
NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc) {
for (NodeSet cluster : clusters) {
joinNodeCluster(cluster, dc, ec, tlc);
}
}


void
NBNodeCont::joinNodeCluster(NodeSet cluster, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc, NBNode* predefined) {
const bool origNames = OptionsCont::getOptions().getBool("output.original-names");
for (NodeClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
NodeSet cluster = *i;
assert(cluster.size() > 1);
Position pos;
bool setTL;
std::string id = "cluster";
TrafficLightType type;
SumoXMLNodeType nodeType = NODETYPE_UNKNOWN;
analyzeCluster(cluster, id, pos, setTL, type, nodeType);
assert(cluster.size() > 1);
Position pos;
bool setTL;
std::string id = "cluster";
TrafficLightType type;
SumoXMLNodeType nodeType = NODETYPE_UNKNOWN;
analyzeCluster(cluster, id, pos, setTL, type, nodeType);
NBNode* newNode = nullptr;
if (predefined != nullptr) {
newNode = predefined;
} else {
if (!insert(id, pos)) {
// should not fail
WRITE_WARNING("Could not join junctions " + id);
continue;
return;;
}
NBNode* newNode = retrieve(id);
newNode->reinit(pos, nodeType);
if (setTL) {
NBTrafficLightDefinition* tlDef = new NBOwnTLDef(id, newNode, 0, type);
if (!tlc.insert(tlDef)) {
// actually, nothing should fail here
delete tlDef;
throw ProcessError("Could not allocate tls '" + id + "'.");
}
newNode = retrieve(id);
}
std::string tlID = id;
if (predefined != nullptr) {
if (predefined->getType() != NODETYPE_UNKNOWN) {
nodeType = predefined->getType();
}
// collect edges
std::set<NBEdge*> allEdges;
for (NBNode* n : cluster) {
const EdgeVector& edges = n->getEdges();
allEdges.insert(edges.begin(), edges.end());
}

// remap and remove edges which are completely within the new intersection
for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) {
NBEdge* e = (*j);
NBNode* from = e->getFromNode();
NBNode* to = e->getToNode();
if (cluster.count(from) > 0 && cluster.count(to) > 0) {
for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) {
if (e != *l) {
(*l)->replaceInConnections(e, e->getConnections());
}
}
ec.extract(dc, e, true);
allEdges.erase(j++); // erase does not invalidate the other iterators
} else {
++j;
}
Position ppos = predefined->getPosition();
if (ppos.x() != Position::INVALID.x()) {
pos.setx(ppos.x());
}
if (ppos.y() != Position::INVALID.y()) {
pos.sety(ppos.y());
}
if (ppos.z() != Position::INVALID.z()) {
pos.setz(ppos.z());
}
}
newNode->reinit(pos, nodeType);
if (setTL && !newNode->isTLControlled()) {
NBTrafficLightDefinition* tlDef = new NBOwnTLDef(tlID, newNode, 0, type);
if (!tlc.insert(tlDef)) {
// actually, nothing should fail here
delete tlDef;
throw ProcessError("Could not allocate tls '" + id + "'.");
}
}
// collect edges
std::set<NBEdge*> allEdges;
for (NBNode* n : cluster) {
const EdgeVector& edges = n->getEdges();
allEdges.insert(edges.begin(), edges.end());
}

// remap edges which are incoming / outgoing
for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) {
NBEdge* e = (*j);
std::vector<NBEdge::Connection> conns = e->getConnections();
const bool outgoing = cluster.count(e->getFromNode()) > 0;
NBNode* from = outgoing ? newNode : e->getFromNode();
NBNode* to = outgoing ? e->getToNode() : newNode;
if (origNames) {
if (outgoing) {
e->setParameter("origFrom", e->getFromNode()->getID());
} else {
e->setParameter("origTo", e->getToNode()->getID());
// remap and remove edges which are completely within the new intersection
for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end();) {
NBEdge* e = (*j);
NBNode* from = e->getFromNode();
NBNode* to = e->getToNode();
if (cluster.count(from) > 0 && cluster.count(to) > 0) {
for (std::set<NBEdge*>::iterator l = allEdges.begin(); l != allEdges.end(); ++l) {
if (e != *l) {
(*l)->replaceInConnections(e, e->getConnections());
}
}
e->reinitNodes(from, to);
// re-add connections which previously existed and may still valid.
// connections to removed edges will be ignored
for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) {
e->addLane2LaneConnection((*k).fromLane, (*k).toEdge, (*k).toLane, NBEdge::L2L_USER, false, (*k).mayDefinitelyPass);
if ((*k).fromLane >= 0 && (*k).fromLane < e->getNumLanes() && e->getLaneStruct((*k).fromLane).connectionsDone) {
// @note (see NIImporter_DlrNavteq::ConnectedLanesHandler)
e->declareConnectionsAsLoaded(NBEdge::INIT);
}
ec.extract(dc, e, true);
allEdges.erase(j++); // erase does not invalidate the other iterators
} else {
++j;
}
}

// remap edges which are incoming / outgoing
for (std::set<NBEdge*>::iterator j = allEdges.begin(); j != allEdges.end(); ++j) {
NBEdge* e = (*j);
std::vector<NBEdge::Connection> conns = e->getConnections();
const bool outgoing = cluster.count(e->getFromNode()) > 0;
NBNode* from = outgoing ? newNode : e->getFromNode();
NBNode* to = outgoing ? e->getToNode() : newNode;
if (origNames) {
if (outgoing) {
e->setParameter("origFrom", e->getFromNode()->getID());
} else {
e->setParameter("origTo", e->getToNode()->getID());
}
}
// remove original nodes
registerJoinedCluster(cluster);
for (NodeSet::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
erase(*j);
e->reinitNodes(from, to);
// re-add connections which previously existed and may still valid.
// connections to removed edges will be ignored
for (std::vector<NBEdge::Connection>::iterator k = conns.begin(); k != conns.end(); ++k) {
e->addLane2LaneConnection((*k).fromLane, (*k).toEdge, (*k).toLane, NBEdge::L2L_USER, false, (*k).mayDefinitelyPass);
if ((*k).fromLane >= 0 && (*k).fromLane < e->getNumLanes() && e->getLaneStruct((*k).fromLane).connectionsDone) {
// @note (see NIImporter_DlrNavteq::ConnectedLanesHandler)
e->declareConnectionsAsLoaded(NBEdge::INIT);
}
}
}
// remove original nodes
registerJoinedCluster(cluster);
for (NodeSet::const_iterator j = cluster.begin(); j != cluster.end(); ++j) {
erase(*j);
}
}


Expand Down
5 changes: 3 additions & 2 deletions src/netbuild/NBNodeCont.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class NBNodeCont {
/** @brief add ids of nodes which shall be joined into a single node
* @param[in] cluster The cluster to add
*/
void addCluster2Join(std::set<std::string> cluster);
void addCluster2Join(std::set<std::string> cluster, NBNode* node);

/// @brief Joins loaded junction clusters (see NIXMLNodesHandler)
int joinLoadedClusters(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc);
Expand Down Expand Up @@ -329,6 +329,7 @@ class NBNodeCont {

/// @brief joins the given node clusters
void joinNodeClusters(NodeClusters clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc);
void joinNodeCluster(NodeSet clusters, NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tlc, NBNode* predefined = nullptr);

/// @}

Expand Down Expand Up @@ -360,7 +361,7 @@ class NBNodeCont {
std::set<std::string> myJoinExclusions;

/// @brief loaded sets of node ids to join (cleared after use)
std::vector<std::set<std::string> > myClusters2Join;
std::vector<std::pair<std::set<std::string>, NBNode*> > myClusters2Join;

/// @brief sets of node ids which were joined
std::vector<std::set<std::string> > myJoinedClusters;
Expand Down
20 changes: 18 additions & 2 deletions src/netimport/NIXMLNodesHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,25 @@ void
NIXMLNodesHandler::addJoinCluster(const SUMOSAXAttributes& attrs) {
bool ok = true;
const std::string clusterString = attrs.get<std::string>(SUMO_ATTR_NODES, nullptr, ok);
const std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
std::sort(ids.begin(), ids.end());

myID = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "cluster_" + joinToString(ids, "_"));

Position myPosition = Position::INVALID;
if (attrs.hasAttribute(SUMO_ATTR_X)) {
myPosition.setx(attrs.get<double>(SUMO_ATTR_X, myID.c_str(), ok));
}
if (attrs.hasAttribute(SUMO_ATTR_Y)) {
myPosition.sety(attrs.get<double>(SUMO_ATTR_Y, myID.c_str(), ok));
}
if (attrs.hasAttribute(SUMO_ATTR_Z)) {
myPosition.setz(attrs.get<double>(SUMO_ATTR_Z, myID.c_str(), ok));
}

NBNode* node = processNodeType(attrs, nullptr, myID, myPosition, false, myNodeCont, myTLLogicCont);
if (ok) {
myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()));
myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()), node);
}
}

Expand Down

0 comments on commit 8a2eb80

Please sign in to comment.