polygonizeedgering.cpp

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

CPP
334
字号
/********************************************************************** * $Id: polygonizeEdgeRing.cpp,v 1.8.2.1 2005/06/17 15:07:48 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/opPolygonize.h>//#define DEBUG_ALLOC 1namespace geos {/* * Find the innermost enclosing shell polygonizeEdgeRing containing * the argument polygonizeEdgeRing, if any. * The innermost enclosing ring is the <i>smallest</i> enclosing ring. * The algorithm used depends on the fact that: *  * ring A contains ring B iff envelope(ring A) contains envelope(ring B) *  * This routine is only safe to use if the chosen point of the hole * is known to be properly contained in a shell * (which is guaranteed to be the case if the hole does not touch its shell) * * @return containing polygonizeEdgeRing, if there is one * @return null if no containing polygonizeEdgeRing is found */polygonizeEdgeRing *polygonizeEdgeRing::findEdgeRingContaining(polygonizeEdgeRing *testEr,	vector<polygonizeEdgeRing*> *shellList){	LinearRing *testRing=testEr->getRingInternal();	if ( ! testRing ) return NULL;	const Envelope *testEnv=testRing->getEnvelopeInternal();	Coordinate testPt=testRing->getCoordinateN(0);	polygonizeEdgeRing *minShell=NULL;	const Envelope *minEnv=NULL;	for(int i=0;i<(int)shellList->size();i++) {		polygonizeEdgeRing *tryShell=(*shellList)[i];		LinearRing *tryRing=tryShell->getRingInternal();		const Envelope *tryEnv=tryRing->getEnvelopeInternal();		if (minShell!=NULL) minEnv=minShell->getRingInternal()->getEnvelopeInternal();		bool isContained=false;		// the hole envelope cannot equal the shell envelope		if (tryEnv->equals(testEnv)) continue;		const CoordinateSequence *tryCoords =			tryRing->getCoordinatesRO();		testPt=ptNotInList(testRing->getCoordinatesRO(),			tryCoords);		if (tryEnv->contains(testEnv)			&& cga.isPointInRing(testPt, tryCoords))				isContained=true;		// check if this new containing ring is smaller than the current minimum ring		if (isContained) {			if (minShell==NULL || minEnv->contains(tryEnv)) {				minShell=tryShell;			}		}	}	return minShell;}/* * Finds a point in a list of points which is not contained in another * list of points * @param testPts the CoordinateSequence to test * @param pts the CoordinateSequence to test the input points against * @return a Coordinate from <code>testPts</code> which is not * in <code>pts</code>,  * or <code>nullCoord</code> */const Coordinate&polygonizeEdgeRing::ptNotInList(const CoordinateSequence *testPts,	const CoordinateSequence *pts){	for (int i=0; i<testPts->getSize(); i++) {		const Coordinate& testPt=testPts->getAt(i);		if (isInList(testPt, pts))			return testPt;	}	return Coordinate::nullCoord;}/* * Tests whether a given point is in an array of points. * Uses a value-based test. * * @param pt a Coordinate for the test point * @param pts a CoordinateSequence to test pt against * @return <code>true</code> if the point is in the array */boolpolygonizeEdgeRing::isInList(const Coordinate& pt,	const CoordinateSequence *pts){	for (int i=0; i < pts->getSize(); i++) {		if (pt==pts->getAt(i))			return false;	}	return true;}polygonizeEdgeRing::polygonizeEdgeRing(const GeometryFactory *newFactory){#ifdef DEBUG_ALLOC	cerr<<"["<<this<<"] polygonizeEdgeRing(factory)"<<endl;#endif // DEBUG_ALLOC	deList=new vector<const planarDirectedEdge*>();	// cache the following data for efficiency	ring=NULL;	ringPts=NULL;	holes=NULL;	factory=newFactory;}polygonizeEdgeRing::~polygonizeEdgeRing(){#ifdef DEBUG_ALLOC	cerr<<"["<<this<<"] ~polygonizeEdgeRing()"<<endl;#endif // DEBUG_ALLOC	delete deList;	if ( holes )	{		for (int i=0; i<(int)holes->size(); i++) delete (*holes)[i];		delete holes;	}	delete ring;	delete ringPts;}/* * Adds a planarDirectedEdge which is known to form part of this ring. * @param de the planarDirectedEdge to add. */voidpolygonizeEdgeRing::add(const planarDirectedEdge *de){	deList->push_back(de);}/** * Tests whether this ring is a hole. * Due to the way the edges in the polyongization graph are linked, * a ring is a hole if it is oriented counter-clockwise. * @return <code>true</code> if this ring is a hole */boolpolygonizeEdgeRing::isHole(){	getRingInternal();	return cga.isCCW(ring->getCoordinatesRO());}/** * Adds a hole to the polygon formed by this ring. * @param hole the {@link LinearRing} forming the hole. */voidpolygonizeEdgeRing::addHole(LinearRing *hole){	if (holes==NULL)		holes=new vector<Geometry*>();	holes->push_back((Geometry *)hole);}/* * Computes the Polygon formed by this ring and any contained holes. * LinearRings ownership is transferred to returned polygon. * Subsequent calls to the function will return NULL. * * @return the Polygon formed by this ring and its holes. */Polygon*polygonizeEdgeRing::getPolygon(){	Polygon *poly=factory->createPolygon(ring, holes);	ring=NULL;	holes=NULL;	return poly;}/* * Tests if the LinearRing formed by this edge ring is topologically valid. */boolpolygonizeEdgeRing::isValid(){	if ( ! getRingInternal() ) return false; // computes cached ring	return ring->isValid();}/* * Computes the list of coordinates which are contained in this ring. * The coordinatea are computed once only and cached. * * @return a CoordinateSequence for this ring */CoordinateSequence*polygonizeEdgeRing::getCoordinates(){	if (ringPts==NULL)	{		ringPts=factory->getCoordinateSequenceFactory()->create(NULL);		for (int i=0;i<(int)deList->size();i++) {			const planarDirectedEdge *de=(*deList)[i];			PolygonizeEdge *edge=(PolygonizeEdge*) de->getEdge();			addEdge(edge->getLine()->getCoordinatesRO(),				de->getEdgeDirection(), ringPts);		}	}	return ringPts;}/* * Gets the coordinates for this ring as a LineString. * Used to return the coordinates in this ring * as a valid geometry, when it has been detected that the ring * is topologically invalid. * @return a LineString containing the coordinates in this ring */LineString*polygonizeEdgeRing::getLineString(){	getCoordinates();	return factory->createLineString(*ringPts);}/* * Returns this ring as a LinearRing, or null if an Exception occurs while * creating it (such as a topology problem). Details of problems are written to * standard output. */LinearRing *polygonizeEdgeRing::getRingInternal(){	if (ring!=NULL) return ring;	getCoordinates();	try {		ring=factory->createLinearRing(*ringPts);	} catch (...) {		return NULL;	}	return ring;}/* * Returns this ring as a LinearRing, or null if an Exception occurs while * creating it (such as a topology problem). Details of problems are written to * standard output. * Caller gets ownership of ring. */LinearRing *polygonizeEdgeRing::getRingOwnership(){	LinearRing *ret = getRingInternal();	ring = NULL;	return ret;}voidpolygonizeEdgeRing::addEdge(const CoordinateSequence *coords, bool isForward,	CoordinateSequence *coordList){	if (isForward) {		for (int i=0; i < coords->getSize(); i++) {			coordList->add(coords->getAt(i), false);		}	} else {		for (int i=coords->getSize()-1; i >= 0; i--) {			coordList->add(coords->getAt(i), false);		}	}}}/********************************************************************** * $Log: polygonizeEdgeRing.cpp,v $ * Revision 1.8.2.1  2005/06/17 15:07:48  strk * Polygonizer segfault fix * * Revision 1.8  2004/10/27 13:57:07  strk * Added some debugging lines (disabled by default) * * Revision 1.7  2004/10/26 16:09:21  strk * Some more intentation and envelope equality check fix. * * Revision 1.6  2004/10/19 19:51:14  strk * Fixed many leaks and bugs in Polygonizer. * Output still bogus. * * Revision 1.5  2004/10/13 10:03:02  strk * Added missing linemerge and polygonize operation. * Bug fixes and leaks removal from the newly added modules and * planargraph (used by them). * Some comments and indentation changes. * * Revision 1.4  2004/07/08 19:34:50  strk * Mirrored JTS interface of CoordinateSequence, factory and * default implementations. * Added DefaultCoordinateSequenceFactory::instance() function. * * Revision 1.3  2004/07/02 13:28:29  strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.2  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.1  2004/04/08 04:53:56  ybychkov * "operation/polygonize" ported from JTS 1.4 * * **********************************************************************/

⌨️ 快捷键说明

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