/** * Marks all edges from the graph which are "dangles". * Dangles are which are incident on a node with degree 1. * This process is recursive, since removing a dangling edge * may result in another edge becoming a dangle. * In order to handle large recursion depths efficiently, * an explicit recursion stack is used * * @return a List containing the LineStrings that formed dangles */ vector<const LineString*>* PolygonizeGraph::deleteDangles() { vector<planarNode*> *nodesToRemove=findNodesOfDegree(1); vector<const LineString*> *dangleLines=new vector<const LineString*>(); vector<planarNode*> nodeStack; for(int i=0;i<(int)nodesToRemove->size();i++) { nodeStack.push_back((*nodesToRemove)[i]); } delete nodesToRemove; while (!nodeStack.empty()) { planarNode *node=nodeStack[nodeStack.size()-1]; nodeStack.pop_back(); deleteAllEdges(node); vector<planarDirectedEdge*> *nodeOutEdges=node->getOutEdges()->getEdges(); for(int j=0;j<(int)nodeOutEdges->size();j++) { PolygonizeDirectedEdge *de=(PolygonizeDirectedEdge*) (*nodeOutEdges)[j]; // delete this edge and its sym de->setMarked(true); PolygonizeDirectedEdge *sym=(PolygonizeDirectedEdge*) de->getSym(); if (sym != NULL) sym->setMarked(true); // save the line as a dangle PolygonizeEdge *e=(PolygonizeEdge*) de->getEdge(); dangleLines->push_back(e->getLine()); planarNode *toNode=de->getToNode(); // add the toNode to the list to be processed, if it is now a dangle if (getDegreeNonDeleted(toNode)==1) nodeStack.push_back(toNode); } } return dangleLines; }
/* public */ void PolygonizeGraph::deleteDangles(std::vector<const LineString*>& dangleLines) { std::vector<Node*> nodeStack; findNodesOfDegree(1, nodeStack); std::set<const LineString*> uniqueDangles; while (!nodeStack.empty()) { Node *node=nodeStack.back(); nodeStack.pop_back(); deleteAllEdges(node); std::vector<DirectedEdge*> &nodeOutEdges=node->getOutEdges()->getEdges(); for(unsigned int j=0; j<nodeOutEdges.size(); ++j) { PolygonizeDirectedEdge *de=(PolygonizeDirectedEdge*)nodeOutEdges[j]; // delete this edge and its sym de->setMarked(true); PolygonizeDirectedEdge *sym=(PolygonizeDirectedEdge*) de->getSym(); if (sym != NULL) sym->setMarked(true); // save the line as a dangle PolygonizeEdge *e=(PolygonizeEdge*) de->getEdge(); const LineString* ls = e->getLine(); if ( uniqueDangles.insert(ls).second ) dangleLines.push_back(ls); Node *toNode=de->getToNode(); // add the toNode to the list to be processed, // if it is now a dangle if (getDegreeNonDeleted(toNode)==1) nodeStack.push_back(toNode); } } }