bufferbuilder.cpp

来自「一个很好的vc底层代码」· C++ 代码 · 共 399 行

CPP
399
字号
/********************************************************************** * $Id: BufferBuilder.cpp,v 1.25 2004/12/08 13:54:43 strk Exp $ * * GEOS - Geometry Engine Open Source * http://geos.refractions.net * * Copyright (C) 2001-2002 Vivid Solutions 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>#include <geos/profiler.h>#ifndef DEBUG#define DEBUG 0#endifnamespace geos {#if PROFILEstatic Profiler *profiler = Profiler::instance();#endif/*** Compute the change in depth as an edge is crossed from R to L*/intBufferBuilder::depthDelta(Label *label){	int lLoc=label->getLocation(0, Position::LEFT);	int rLoc=label->getLocation(0, Position::RIGHT);	if (lLoc== Location::INTERIOR && rLoc== Location::EXTERIOR)		return 1;	else if (lLoc== Location::EXTERIOR && rLoc== Location::INTERIOR)		return -1;	return 0;}static RobustCGAlgorithms rCGA;CGAlgorithms *BufferBuilder::cga=&rCGA;/** * Creates a new BufferBuilder */BufferBuilder::BufferBuilder():	quadrantSegments(OffsetCurveBuilder::DEFAULT_QUADRANT_SEGMENTS),	endCapStyle(BufferOp::CAP_ROUND),	workingPrecisionModel(NULL),	edgeList(new EdgeList()){}BufferBuilder::~BufferBuilder(){	delete edgeList;	for (unsigned int i=0; i<newLabels.size(); i++)		delete newLabels[i];}/** * Sets the number of segments used to approximate a angle fillet * * @param quadrantSegments the number of segments in a fillet for a quadrant */voidBufferBuilder::setQuadrantSegments(int nQuadrantSegments){	quadrantSegments=nQuadrantSegments;}/** * Sets the precision model to use during the curve computation and noding, * if it is different to the precision model of the Geometry-> * If the precision model is less than the precision of the Geometry * precision model, * the Geometry must have previously been rounded to that precision-> * * @param pm the precision model to use */voidBufferBuilder::setWorkingPrecisionModel(PrecisionModel *pm){	workingPrecisionModel=pm;}voidBufferBuilder::setEndCapStyle(int nEndCapStyle){	endCapStyle=nEndCapStyle;}Geometry*BufferBuilder::buffer(Geometry *g, double distance)	// throw(GEOSException *){	const PrecisionModel *precisionModel=workingPrecisionModel;	if (precisionModel==NULL)		precisionModel=g->getPrecisionModel();	// factory must be the same as the one used by the input	geomFact=g->getFactory();	OffsetCurveBuilder curveBuilder(precisionModel, quadrantSegments);	curveBuilder.setEndCapStyle(endCapStyle);	OffsetCurveSetBuilder curveSetBuilder(g, distance, &curveBuilder);	vector<SegmentString*> *bufferSegStrList=curveSetBuilder.getCurves();	// short-circuit test	if (bufferSegStrList->size()<=0) {		Geometry *emptyGeom=geomFact->createGeometryCollection(NULL);		return emptyGeom;	}#if DEBUG	cerr<<"BufferBuilder::buffer computing NodedEdges"<<endl;#endif#if PROFILE	profiler->start("BufferBuilder::computeNodedEdges()");#endif	computeNodedEdges(bufferSegStrList, precisionModel);#if PROFILE	profiler->stop("BufferBuilder::computeNodedEdges()");#endif#if DEBUG	cerr<<"BufferBuilder::buffer finished computing NodedEdges"<<endl;#endif	Geometry* resultGeom=NULL;	vector<Geometry*> *resultPolyList=NULL;	vector<BufferSubgraph*> *subgraphList=NULL;	try {		PlanarGraph graph(new OverlayNodeFactory());		graph.addEdges(edgeList->getEdges());		subgraphList=createSubgraphs(&graph);		PolygonBuilder polyBuilder(geomFact,cga);		buildSubgraphs(subgraphList, &polyBuilder);		resultPolyList=polyBuilder.getPolygons();		resultGeom=geomFact->buildGeometry(resultPolyList);	} catch (GEOSException *exc) {		for (unsigned int i=0; i<subgraphList->size(); i++)			delete (*subgraphList)[i];		delete subgraphList;		//for (unsigned int i=0; i<resultPolyList->size(); i++)		//	delete (*resultPolyList)[i];		//delete resultPolyList;		throw;	} 	for (unsigned int i=0; i<subgraphList->size(); i++)		delete (*subgraphList)[i];	delete subgraphList;	return resultGeom;}voidBufferBuilder::computeNodedEdges(vector<SegmentString*> *bufferSegStrList, const PrecisionModel *precisionModel)	// throw(GEOSException *){	//BufferCurveGraphNoder noder=new BufferCurveGraphNoder(geomFact->getPrecisionModel());	IteratedNoder noder(precisionModel);	vector<SegmentString*> *nodedSegStrings = NULL;		try 	{#if DEBUG		cerr<<"BufferBuilder::computeNodedEdges: getting nodedSegString"<<endl;#endif		nodedSegStrings=noder.node(bufferSegStrList);#if DEBUG		cerr<<"BufferBuilder::computeNodedEdges: done getting nodedSegString"<<endl;#endif		// DEBUGGING ONLY		//BufferDebug->saveEdges(nodedEdges, "run" + BufferDebug->runCount + "_nodedEdges");#if DEBUG		cerr<<"BufferBuilder::computeNodedEdges: setting label for "<<nodedSegStrings->size()<<" nodedSegStrings"<<endl;#endif#if PROFILE	profiler->start("BufferBuilder::computeNodedEdges: labeling");#endif		for (unsigned int i=0;i<nodedSegStrings->size();i++) {			SegmentString *segStr=(*nodedSegStrings)[i];			Label *oldLabel=(Label*) segStr->getContext();			Edge *edge=new Edge((CoordinateSequence*) segStr->getCoordinates(), new Label(oldLabel));			insertEdge(edge);		}#if PROFILE	profiler->stop("BufferBuilder::computeNodedEdges: labeling");#endif#if DEBUG		cerr<<"BufferBuilder::computeNodedEdges: labeling for "<<nodedSegStrings->size()<<" nodedSegStrings done"<<endl;#endif		//saveEdges(edgeList->getEdges(), "run" + runCount + "_collapsedEdges");	} catch (...) {		delete nodedSegStrings;		throw;	} 	delete nodedSegStrings;}/** * Inserted edges are checked to see if an identical edge already exists-> * If so, the edge is not inserted, but its label is merged * with the existing edge-> */voidBufferBuilder::insertEdge(Edge *e){	//<FIX> MD 8 Oct 03  speed up identical edge lookup	// fast lookup#if PROFILE	profiler->start("EdgeList::findEqualEdge()");#endif	Edge *existingEdge=edgeList->findEqualEdge(e);#if PROFILE	profiler->stop("EdgeList::findEqualEdge()");#endif	// If an identical edge already exists, simply update its label	if (existingEdge != NULL) {		Label *existingLabel=existingEdge->getLabel();		Label *labelToMerge=e->getLabel();		// check if new edge is in reverse direction to existing edge		// if so, must flip the label before merging it		if (! existingEdge->isPointwiseEqual(e))		{			labelToMerge=new Label(e->getLabel());			labelToMerge->flip();			newLabels.push_back(labelToMerge);		}		existingLabel->merge(labelToMerge);		// compute new depth delta of sum of edges		int mergeDelta=depthDelta(labelToMerge);		int existingDelta=existingEdge->getDepthDelta();		int newDelta=existingDelta + mergeDelta;		existingEdge->setDepthDelta(newDelta);		delete e;	} else {   // no matching existing edge was found		// add this new edge to the list of edges in this graph		//e->setName(name + edges->size());		edgeList->add(e);		e->setDepthDelta(depthDelta(e->getLabel()));	}}bool BufferSubgraphGT(BufferSubgraph *first, BufferSubgraph *second) {	if (first->compareTo(second)>=0)		return true;	else		return false;}vector<BufferSubgraph*>*BufferBuilder::createSubgraphs(PlanarGraph *graph){	vector<BufferSubgraph*> *subgraphList=new vector<BufferSubgraph*>();	vector<Node*> *n=graph->getNodes();	for (unsigned int i=0;i<n->size();i++) {		Node *node=(*n)[i];		if (!node->isVisited()) {			BufferSubgraph *subgraph=new BufferSubgraph(cga);			subgraph->create(node);			subgraphList->push_back(subgraph);		}	}	delete n;	/**	* Sort the subgraphs in descending order of their rightmost coordinate->	* This ensures that when the Polygons for the subgraphs are built,	* subgraphs for shells will have been built before the subgraphs for	* any holes they contain->	*/	sort(subgraphList->begin(),subgraphList->end(),BufferSubgraphGT);	return subgraphList;}/*** Completes the building of the input subgraphs by depth-labelling them,* and adds them to the PolygonBuilder->* The subgraph list must be sorted in rightmost-coordinate order->** @param subgraphList the subgraphs to build* @param polyBuilder the PolygonBuilder which will build the final polygons*/voidBufferBuilder::buildSubgraphs(vector<BufferSubgraph*> *subgraphList,PolygonBuilder *polyBuilder){	vector<BufferSubgraph*> processedGraphs;	for (unsigned int i=0;i<subgraphList->size();i++) {		BufferSubgraph *subgraph=(*subgraphList)[i];		Coordinate *p=subgraph->getRightmostCoordinate();		SubgraphDepthLocater locater=SubgraphDepthLocater(&processedGraphs);		int outsideDepth=locater.getDepth(*p);		subgraph->computeDepth(outsideDepth);		subgraph->findResultEdges();		processedGraphs.push_back(subgraph);		polyBuilder->add(subgraph->getDirectedEdges(), subgraph->getNodes());	}}}/********************************************************************** * $Log: BufferBuilder.cpp,v $ * Revision 1.25  2004/12/08 13:54:43  strk * gcc warnings checked and fixed, general cleanups. * * Revision 1.24  2004/11/04 19:08:07  strk * Cleanups, initializers list, profiling. * * Revision 1.23  2004/11/01 16:43:04  strk * Added Profiler code. * Temporarly patched a bug in DoubleBits (must check drawbacks). * Various cleanups and speedups. * * Revision 1.22  2004/07/13 08:33:53  strk * Added missing virtual destructor to virtual classes. * Fixed implicit unsigned int -> int casts * * Revision 1.21  2004/07/08 19:34:49  strk * Mirrored JTS interface of CoordinateSequence, factory and * default implementations. * Added DefaultCoordinateSequenceFactory::instance() function. * * Revision 1.20  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.19  2004/07/01 14:12:44  strk * * Geometry constructors come now in two flavors: * 	- deep-copy args (pass-by-reference) * 	- take-ownership of args (pass-by-pointer) * Same functionality is available through GeometryFactory, * including buildGeometry(). * * Revision 1.18  2004/06/15 20:10:31  strk * updated to respect deep-copy GeometryCollection interface * * Revision 1.17  2004/06/15 20:01:58  strk * Empty geometry creation call made using NULL instead of newly created empty vector (will be faster) * * Revision 1.16  2004/05/26 13:12:58  strk * Removed try/catch block from ::buildSubgraphs * * Revision 1.15  2004/05/26 09:49:03  strk * PlanarGraph made local to ::buffer instead of Class private. * * Revision 1.14  2004/05/05 16:57:48  strk * Rewritten static cga allocation to avoid copy constructor calls. * * Revision 1.13  2004/05/05 16:36:46  strk * Avoid use of copy c'tors on local objects initializzation * * Revision 1.12  2004/05/05 13:08:01  strk * Leaks fixed, explicit allocations/deallocations reduced. * * Revision 1.11  2004/05/05 10:54:48  strk * Removed some private static heap explicit allocation, less cleanup done by * the unloader. * * Revision 1.10  2004/05/03 22:56:44  strk * leaks fixed, exception specification omitted. * * Revision 1.9  2004/05/03 17:15:38  strk * leaks on exception fixed. * * Revision 1.8  2004/05/03 10:43:43  strk * Exception specification considered harmful - left as comment. * * Revision 1.7  2004/04/30 09:15:28  strk * Enlarged exception specifications to allow for AssertionFailedException. * Added missing initializers. * * Revision 1.6  2004/04/23 00:02:18  strk * const-correctness changes * * Revision 1.5  2004/04/20 10:58:04  strk * More memory leaks removed. * * Revision 1.4  2004/04/19 15:14:46  strk * Added missing virtual destructor in SpatialIndex class. * Memory leaks fixes. Const and throw specifications added. * * Revision 1.3  2004/04/19 12:51:01  strk * Memory leaks fixes. Throw specifications added. * * Revision 1.2  2004/04/14 08:38:52  strk * BufferBuilder constructor missed to initialize workingPrecisionModel * * Revision 1.1  2004/04/10 08:40:01  ybychkov * "operation/buffer" upgraded to JTS 1.4 * * **********************************************************************/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?