buffersubgraph.cpp
来自「一个很好的vc底层代码」· C++ 代码 · 共 318 行
CPP
318 行
/********************************************************************** * $Id: BufferSubgraph.cpp,v 1.12.2.1 2005/06/30 18:31:21 strk Exp $ * * GEOS - Geometry Engine Open Source * http://geos.refractions.net * * Copyright (C) 2001-2002 Vivid Solutions Inc. * Copyright (C) 2005 Refractions Research Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/#include <geos/opBuffer.h>namespace geos {BufferSubgraph::BufferSubgraph(CGAlgorithms *cga): finder(new RightmostEdgeFinder(cga)), dirEdgeList(new vector<DirectedEdge*>()), nodes(new vector<Node*>()), rightMostCoord(NULL), env(NULL){ //dirEdgeList=new vector<DirectedEdge*>(); //nodes=new vector<Node*>(); //rightMostCoord=NULL; //finder=new RightmostEdgeFinder(cga);}BufferSubgraph::~BufferSubgraph() { delete dirEdgeList; delete nodes; delete finder; delete env;}vector<DirectedEdge*>* BufferSubgraph::getDirectedEdges() { return dirEdgeList;}vector<Node*>* BufferSubgraph::getNodes() { return nodes;}/*** Gets the rightmost coordinate in the edges of the subgraph*/Coordinate* BufferSubgraph::getRightmostCoordinate() { return rightMostCoord;}/*** Creates the subgraph consisting of all edges reachable from this node.* Finds the edges in the graph and the rightmost coordinate.** @param node a node to start the graph traversal from*/void BufferSubgraph::create(Node *node) { addReachable(node); finder->findEdge(dirEdgeList); rightMostCoord=&(finder->getCoordinate());}/*** Adds all nodes and edges reachable from this node to the subgraph.* Uses an explicit stack to avoid a large depth of recursion.** @param node a node known to be in the subgraph*/void BufferSubgraph::addReachable(Node *startNode) { vector<Node*> *nodeStack=new vector<Node*>(); nodeStack->push_back(startNode); while (!nodeStack->empty()) { Node *node=*(nodeStack->end()-1); nodeStack->pop_back(); add(node, nodeStack); } delete nodeStack;}/*** Adds the argument node and all its out edges to the subgraph* @param node the node to add* @param nodeStack the current set of nodes being traversed*/void BufferSubgraph::add(Node *node, vector<Node*> *nodeStack){ node->setVisited(true); nodes->push_back(node); vector<EdgeEnd*> *ees=node->getEdges()->getEdges(); for(int i=0;i<(int)ees->size();i++) { DirectedEdge *de=(DirectedEdge*) (*ees)[i]; dirEdgeList->push_back(de); DirectedEdge *sym=de->getSym(); Node *symNode=sym->getNode(); /** * NOTE: this is a depth-first traversal of the graph. * This will cause a large depth of recursion. * It might be better to do a breadth-first traversal. */ if (! symNode->isVisited()) nodeStack->push_back(symNode); }}void BufferSubgraph::clearVisitedEdges() { unsigned int size = dirEdgeList->size(); for(int i=0; i<size; ++i) { DirectedEdge *de=(*dirEdgeList)[i]; de->setVisited(false); }}void BufferSubgraph::computeDepth(int outsideDepth) { clearVisitedEdges(); // find an outside edge to assign depth to DirectedEdge *de=finder->getEdge(); //Node *n=de->getNode(); //Label *label=de->getLabel(); // right side of line returned by finder is on the outside de->setEdgeDepths(Position::RIGHT, outsideDepth); copySymDepths(de); //computeNodeDepth(n, de); computeDepths(de);}voidBufferSubgraph::computeNodeDepth(Node *n) // throw(TopologyException *){ // find a visited dirEdge to start at DirectedEdge *startEdge=NULL; vector<EdgeEnd*> *ees=n->getEdges()->getEdges(); for(int i=0;i<(int)ees->size();i++) { DirectedEdge *de=(DirectedEdge*) (*ees)[i]; if (de->isVisited() || de->getSym()->isVisited()) { startEdge=de; break; } } // MD - testing Result: breaks algorithm //if (startEdge==null) return; Assert::isTrue(startEdge!=NULL, "unable to find edge to compute depths at " + n->getCoordinate().toString()); ((DirectedEdgeStar*) n->getEdges())->computeDepths(startEdge); // copy depths to sym edges vector<EdgeEnd*> *ees1=n->getEdges()->getEdges(); for(int j=0;j<(int)ees1->size();j++) { DirectedEdge *de=(DirectedEdge*) (*ees)[j]; de->setVisited(true); copySymDepths(de); }}void BufferSubgraph::copySymDepths(DirectedEdge *de){ DirectedEdge *sym=de->getSym(); sym->setDepth(Position::LEFT, de->getDepth(Position::RIGHT)); sym->setDepth(Position::RIGHT, de->getDepth(Position::LEFT));}/*** Find all edges whose depths indicates that they are in the result area(s).* Since we want polygon shells to be* oriented CW, choose dirEdges with the interior of the result on the RHS.* Mark them as being in the result.* Interior Area edges are the result of dimensional collapses.* They do not form part of the result area boundary.*/void BufferSubgraph::findResultEdges() { for(int i=0;i<(int)dirEdgeList->size();i++) { DirectedEdge *de=(*dirEdgeList)[i]; /** * Select edges which have an interior depth on the RHS * and an exterior depth on the LHS. * Note that because of weird rounding effects there may be * edges which have negative depths! Negative depths * count as "outside". */ // <FIX> - handle negative depths if ( de->getDepth(Position::RIGHT)>=1 && de->getDepth(Position::LEFT)<=0 && !de->isInteriorAreaEdge()) { de->setInResult(true); //Debug.print("in result "); Debug.println(de); } }}/*** BufferSubgraphs are compared on the x-value of their rightmost Coordinate.* This defines a partial ordering on the graphs such that:* <p>* g1 >= g2 <==> Ring(g2) does not contain Ring(g1)* <p>* where Polygon(g) is the buffer polygon that is built from g.* <p>* This relationship is used to sort the BufferSubgraphs so that shells are guaranteed to* be built before holes.*/int BufferSubgraph::compareTo(void* o) { BufferSubgraph *graph=(BufferSubgraph*) o; if (rightMostCoord->x<graph->rightMostCoord->x) { return -1; } if (rightMostCoord->x>graph->rightMostCoord->x) { return 1; } return 0;}/*** Compute depths for all dirEdges via breadth-first traversal of nodes in graph* @param startEdge edge to start processing with*/// <FIX> MD - use iteration & queue rather than recursion, for speed and robustnessvoid BufferSubgraph::computeDepths(DirectedEdge *startEdge){ vector<Node*> nodesVisited; //Used to be a HashSet vector<Node*> nodeQueue; Node *startNode=startEdge->getNode(); nodeQueue.push_back(startNode); nodesVisited.push_back(startNode); startEdge->setVisited(true); while (! nodeQueue.empty()) { //System.out.println(nodes.size() + " queue: " + nodeQueue.size()); Node *n=nodeQueue[0]; nodeQueue.erase(nodeQueue.begin()); nodesVisited.push_back(n); // compute depths around node, starting at this edge since it has depths assigned computeNodeDepth(n); // add all adjacent nodes to process queue, // unless the node has been visited already vector<EdgeEnd*> *ees=n->getEdges()->getEdges(); for(int i=0;i<(int)ees->size();i++) { DirectedEdge *de=(DirectedEdge*) (*ees)[i]; DirectedEdge *sym=de->getSym(); if (sym->isVisited()) continue; Node *adjNode=sym->getNode(); if (! contains(&nodesVisited,adjNode)) { nodeQueue.push_back(adjNode); nodesVisited.push_back(adjNode); } } }}bool BufferSubgraph::contains(vector<Node*> *nodes,Node *node) { bool result=false; for(int i=0;i<(int)nodes->size();i++) { if (node==(*nodes)[i]) { result=true; break; } } return result;}Envelope *BufferSubgraph::getEnvelope(){ if (env == NULL) { env = new Envelope(); unsigned int size = dirEdgeList->size(); for(unsigned int i=0; i<size; ++i) { DirectedEdge *dirEdge=(*dirEdgeList)[i]; const CoordinateSequence *pts = dirEdge->getEdge()->getCoordinates(); int n = pts->getSize()-1; for (int j=0; j<n; ++j) { env->expandToInclude(pts->getAt(j)); } } } return env;}} // namespace geos/********************************************************************** * $Log: BufferSubgraph.cpp,v $ * Revision 1.12.2.1 2005/06/30 18:31:21 strk * Ported SubgraphDepthLocator optimizations from JTS code * * Revision 1.12 2004/12/08 13:54:43 strk * gcc warnings checked and fixed, general cleanups. * * Revision 1.11 2004/07/07 07:52:13 strk * Removed note about required speedup in BufferSubgraph. * I've made tests with 'sets' and there is actually a big slow down.. * * Revision 1.10 2004/07/02 13:28:27 strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.9 2004/05/19 12:50:53 strk * Removed all try/catch blocks transforming stack allocated-vectors to auto-heap-allocations * * Revision 1.8 2004/05/03 22:56:44 strk * leaks fixed, exception specification omitted. * * Revision 1.7 2004/05/03 17:15:38 strk * leaks on exception fixed. * * Revision 1.6 2004/04/16 12:48:07 strk * Leak fixes. * * Revision 1.5 2004/04/10 08:40:01 ybychkov * "operation/buffer" upgraded to JTS 1.4 * * **********************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?