[geos-commits] r3930 - in trunk/src: operation/polygonize triangulate triangulate/quadedge

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Aug 28 05:35:13 PDT 2013


Author: mloskot
Date: 2013-08-28 05:35:13 -0700 (Wed, 28 Aug 2013)
New Revision: 3930

Modified:
   trunk/src/operation/polygonize/EdgeRing.cpp
   trunk/src/triangulate/IncrementalDelaunayTriangulator.cpp
   trunk/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
Log:
* Replace while(true) with canonical for(;;)
* Warnings clean-up
* Untabify

Modified: trunk/src/operation/polygonize/EdgeRing.cpp
===================================================================
--- trunk/src/operation/polygonize/EdgeRing.cpp	2013-08-28 12:32:13 UTC (rev 3929)
+++ trunk/src/operation/polygonize/EdgeRing.cpp	2013-08-28 12:35:13 UTC (rev 3930)
@@ -27,6 +27,7 @@
 #include <geos/geom/GeometryFactory.h>
 #include <geos/geom/CoordinateSequenceFactory.h>
 #include <geos/algorithm/CGAlgorithms.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <cassert>
@@ -46,50 +47,50 @@
 /*public*/
 EdgeRing *
 EdgeRing::findEdgeRingContaining(EdgeRing *testEr,
-	vector<EdgeRing*> *shellList)
+    vector<EdgeRing*> *shellList)
 {
-	const LinearRing *testRing=testEr->getRingInternal();
-	if ( ! testRing ) return NULL;
-	const Envelope *testEnv=testRing->getEnvelopeInternal();
-	Coordinate testPt=testRing->getCoordinateN(0);
-	EdgeRing *minShell=NULL;
-	const Envelope *minEnv=NULL;
+    const LinearRing *testRing=testEr->getRingInternal();
+    if ( ! testRing ) return NULL;
+    const Envelope *testEnv=testRing->getEnvelopeInternal();
+    Coordinate testPt=testRing->getCoordinateN(0);
+    EdgeRing *minShell=NULL;
+    const Envelope *minEnv=NULL;
 
-	typedef std::vector<EdgeRing*> ERList;
-	for(ERList::size_type i=0, e=shellList->size(); i<e; ++i) {
-		EdgeRing *tryShell=(*shellList)[i];
-		LinearRing *tryRing=tryShell->getRingInternal();
-		const Envelope *tryEnv=tryRing->getEnvelopeInternal();
-		if (minShell!=NULL) minEnv=minShell->getRingInternal()->getEnvelopeInternal();
-		bool isContained=false;
+    typedef std::vector<EdgeRing*> ERList;
+    for(ERList::size_type i=0, e=shellList->size(); i<e; ++i) {
+        EdgeRing *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
+        // the hole envelope cannot equal the shell envelope
 
-		if (tryEnv->equals(testEnv)) continue;
+        if (tryEnv->equals(testEnv)) continue;
 
-		const CoordinateSequence *tryCoords =
-			tryRing->getCoordinatesRO();
+        const CoordinateSequence *tryCoords =
+            tryRing->getCoordinatesRO();
 
-		if ( tryEnv->contains(testEnv) ) {
+        if ( tryEnv->contains(testEnv) ) {
 
-			// TODO: don't copy testPt !
-			testPt = ptNotInList(testRing->getCoordinatesRO(), tryCoords);
+            // TODO: don't copy testPt !
+            testPt = ptNotInList(testRing->getCoordinatesRO(), tryCoords);
 
-			if ( CGAlgorithms::isPointInRing(testPt, tryCoords) ) {
-				isContained=true;
-			}
+            if ( CGAlgorithms::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;
+        // 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;
 }
 
 /*public static*/
@@ -124,125 +125,126 @@
 
 /*public*/
 EdgeRing::EdgeRing(const GeometryFactory *newFactory)
-	:
-	factory(newFactory),
-	ring(0),
-	ringPts(0),
-	holes(0)
+    :
+    factory(newFactory),
+    ring(0),
+    ringPts(0),
+    holes(0)
 {
 #ifdef DEBUG_ALLOC
-	cerr<<"["<<this<<"] EdgeRing(factory)"<<endl;
+    cerr<<"["<<this<<"] EdgeRing(factory)"<<endl;
 #endif // DEBUG_ALLOC
 }
 
 EdgeRing::~EdgeRing()
 {
 #ifdef DEBUG_ALLOC
-	cerr<<"["<<this<<"] ~EdgeRing()"<<endl;
+    cerr<<"["<<this<<"] ~EdgeRing()"<<endl;
 #endif // DEBUG_ALLOC
-	if ( holes )
-	{
-		for (GeomVect::size_type i=0, e=holes->size(); i<e; ++i)
-			delete (*holes)[i];
-		delete holes;
-	}
-	delete ring;
-	delete ringPts;
+    if ( holes )
+    {
+        for (GeomVect::size_type i=0, e=holes->size(); i<e; ++i)
+            delete (*holes)[i];
+        delete holes;
+    }
+    delete ring;
+    delete ringPts;
 }
 
 /*public*/
 void
 EdgeRing::add(const DirectedEdge *de){
-	deList.push_back(de);
+    deList.push_back(de);
 }
 
 /*public*/
 bool
 EdgeRing::isHole(){
-	getRingInternal();
-	return CGAlgorithms::isCCW(ring->getCoordinatesRO());
+    getRingInternal();
+    return CGAlgorithms::isCCW(ring->getCoordinatesRO());
 }
 
 /*public*/
 void
 EdgeRing::addHole(LinearRing *hole)
 {
-	if (holes==NULL)
-		holes=new vector<Geometry*>();
-	holes->push_back(hole);
+    if (holes==NULL)
+        holes=new vector<Geometry*>();
+    holes->push_back(hole);
 }
 
 /*public*/
 Polygon*
 EdgeRing::getPolygon()
 {
-	Polygon *poly=factory->createPolygon(ring, holes);
-	ring=NULL;
-	holes=NULL;
-	return poly;
+    Polygon *poly=factory->createPolygon(ring, holes);
+    ring=NULL;
+    holes=NULL;
+    return poly;
 }
 
 /*public*/
 bool
 EdgeRing::isValid()
 {
-	if ( ! getRingInternal() ) return false; // computes cached ring
-	return ring->isValid();
+    if ( ! getRingInternal() ) return false; // computes cached ring
+    return ring->isValid();
 }
 
 /*private*/
 CoordinateSequence*
 EdgeRing::getCoordinates()
 {
-	if (ringPts==NULL)
-	{
-		ringPts=factory->getCoordinateSequenceFactory()->create(NULL);
-		for (DeList::size_type i=0, e=deList.size(); i<e; ++i) {
-			const DirectedEdge *de=deList[i];
-			assert(dynamic_cast<PolygonizeEdge*>(de->getEdge()));
-			PolygonizeEdge *edge=static_cast<PolygonizeEdge*>(de->getEdge());
-			addEdge(edge->getLine()->getCoordinatesRO(),
-				de->getEdgeDirection(), ringPts);
-		}
-	}
-	return ringPts;
+    if (ringPts==NULL)
+    {
+        ringPts=factory->getCoordinateSequenceFactory()->create(NULL);
+        for (DeList::size_type i=0, e=deList.size(); i<e; ++i) {
+            const DirectedEdge *de=deList[i];
+            assert(dynamic_cast<PolygonizeEdge*>(de->getEdge()));
+            PolygonizeEdge *edge=static_cast<PolygonizeEdge*>(de->getEdge());
+            addEdge(edge->getLine()->getCoordinatesRO(),
+                de->getEdgeDirection(), ringPts);
+        }
+    }
+    return ringPts;
 }
 
 /*public*/
 LineString*
 EdgeRing::getLineString()
 {
-	getCoordinates();
-	return factory->createLineString(*ringPts);
+    getCoordinates();
+    return factory->createLineString(*ringPts);
 }
 
 /*public*/
 LinearRing *
 EdgeRing::getRingInternal()
 {
-	if (ring!=NULL) return ring;
+    if (ring!=NULL) return ring;
 
-	getCoordinates();
-	try {
-		ring=factory->createLinearRing(*ringPts);
-	} catch (const std::exception& e) {
+    getCoordinates();
+    try {
+        ring=factory->createLinearRing(*ringPts);
+    } catch (const std::exception& e) {
 #if GEOS_DEBUG
-		// FIXME: print also ringPts
-		std::cerr << "EdgeRing::getRingInternal: "
-		          << e.what()
-		          << endl;
+        // FIXME: print also ringPts
+        std::cerr << "EdgeRing::getRingInternal: "
+                  << e.what()
+                  << endl;
 #endif
-	}
-	return ring;
+        ::geos::ignore_unused_variable_warning(e);
+    }
+    return ring;
 }
 
 /*public*/
 LinearRing *
 EdgeRing::getRingOwnership()
 {
-	LinearRing *ret = getRingInternal();
-	ring = NULL;
-	return ret;
+    LinearRing *ret = getRingInternal();
+    ring = NULL;
+    return ret;
 }
 
 /*private*/

Modified: trunk/src/triangulate/IncrementalDelaunayTriangulator.cpp
===================================================================
--- trunk/src/triangulate/IncrementalDelaunayTriangulator.cpp	2013-08-28 12:32:13 UTC (rev 3929)
+++ trunk/src/triangulate/IncrementalDelaunayTriangulator.cpp	2013-08-28 12:35:13 UTC (rev 3930)
@@ -28,73 +28,74 @@
 using namespace quadedge;
 
 IncrementalDelaunayTriangulator::IncrementalDelaunayTriangulator(
-		QuadEdgeSubdivision *subdiv) :
-	subdiv(subdiv), isUsingTolerance(subdiv->getTolerance() > 0.0)
+        QuadEdgeSubdivision *subdiv) :
+    subdiv(subdiv), isUsingTolerance(subdiv->getTolerance() > 0.0)
 { 
 }
 
 void IncrementalDelaunayTriangulator::insertSites(const VertexList& vertices)
 {
-	for (VertexList::const_iterator x=vertices.begin(); 
-			x != vertices.end(); ++x) {
-		insertSite(*x);
-	}
+    for (VertexList::const_iterator x=vertices.begin(); 
+            x != vertices.end(); ++x) {
+        insertSite(*x);
+    }
 }
 
 QuadEdge& IncrementalDelaunayTriangulator::insertSite(const Vertex &v)
 {
-	/**
-	 * This code is based on Guibas and Stolfi (1985), with minor modifications
-	 * and a bug fix from Dani Lischinski (Graphic Gems 1993). (The modification
-	 * I believe is the test for the inserted site falling exactly on an
-	 * existing edge. Without this test zero-width triangles have been observed
-	 * to be created)
-	 */
-	QuadEdge *e = subdiv->locate(v);
+    /**
+     * This code is based on Guibas and Stolfi (1985), with minor modifications
+     * and a bug fix from Dani Lischinski (Graphic Gems 1993). (The modification
+     * I believe is the test for the inserted site falling exactly on an
+     * existing edge. Without this test zero-width triangles have been observed
+     * to be created)
+     */
+    QuadEdge *e = subdiv->locate(v);
 
-	if(!e) {
-		throw LocateFailureException("");
-	}
+    if(!e) {
+        throw LocateFailureException("");
+    }
 
-	if (subdiv->isVertexOfEdge(*e, v)) {
-		// point is already in subdivision.
-		return *e; 
-	} 
-	else if (subdiv->isOnEdge(*e, v.getCoordinate())) {
-		// the point lies exactly on an edge, so delete the edge 
-		// (it will be replaced by a pair of edges which have the point as a vertex)
-		e = &e->oPrev();
-		subdiv->remove(e->oNext());
-	}
+    if (subdiv->isVertexOfEdge(*e, v)) {
+        // point is already in subdivision.
+        return *e; 
+    } 
+    else if (subdiv->isOnEdge(*e, v.getCoordinate())) {
+        // the point lies exactly on an edge, so delete the edge 
+        // (it will be replaced by a pair of edges which have the point as a vertex)
+        e = &e->oPrev();
+        subdiv->remove(e->oNext());
+    }
 
-	/**
-	 * Connect the new point to the vertices of the containing triangle 
-	 * (or quadrilateral, if the new point fell on an existing edge.)
-	 */
-	QuadEdge* base = &subdiv->makeEdge(e->orig(), v);
+    /**
+     * Connect the new point to the vertices of the containing triangle 
+     * (or quadrilateral, if the new point fell on an existing edge.)
+     */
+    QuadEdge* base = &subdiv->makeEdge(e->orig(), v);
 
-	QuadEdge::splice(*base, *e);
-	QuadEdge *startEdge = base;
-	do {
-		base = &subdiv->connect(*e, base->sym());
-		e = &base->oPrev();
-	} while (&e->lNext() != startEdge);
+    QuadEdge::splice(*base, *e);
+    QuadEdge *startEdge = base;
+    do {
+        base = &subdiv->connect(*e, base->sym());
+        e = &base->oPrev();
+    } while (&e->lNext() != startEdge);
 
 
-	// Examine suspect edges to ensure that the Delaunay condition
-	// is satisfied.
-	do {
-		QuadEdge* t = &e->oPrev();
-		if (t->dest().rightOf(*e) &&
-				v.isInCircle(e->orig(), t->dest(), e->dest())) {
-			QuadEdge::swap(*e);
-			e = &e->oPrev();
-		} else if (&e->oNext() == startEdge) {
-			return *base; // no more suspect edges.
-		} else {
-			e = &e->oNext().lPrev();
-		}
-	} while (true);
+    // Examine suspect edges to ensure that the Delaunay condition
+    // is satisfied.
+    for (;;)
+    {
+        QuadEdge* t = &e->oPrev();
+        if (t->dest().rightOf(*e) &&
+                v.isInCircle(e->orig(), t->dest(), e->dest())) {
+            QuadEdge::swap(*e);
+            e = &e->oPrev();
+        } else if (&e->oNext() == startEdge) {
+            return *base; // no more suspect edges.
+        } else {
+            e = &e->oNext().lPrev();
+        }
+    }
 }
 
 } //namespace geos.triangulate

Modified: trunk/src/triangulate/quadedge/QuadEdgeSubdivision.cpp
===================================================================
--- trunk/src/triangulate/quadedge/QuadEdgeSubdivision.cpp	2013-08-28 12:32:13 UTC (rev 3929)
+++ trunk/src/triangulate/quadedge/QuadEdgeSubdivision.cpp	2013-08-28 12:35:13 UTC (rev 3930)
@@ -44,427 +44,430 @@
 
 void
 QuadEdgeSubdivision::getTriangleEdges(const QuadEdge &startQE,
-		const QuadEdge* triEdge[3])
+        const QuadEdge* triEdge[3])
 {
-	triEdge[0] = &startQE;
-	triEdge[1] = &triEdge[0]->lNext();
-	triEdge[2] = &triEdge[1]->lNext();
-	if (&triEdge[2]->lNext() != triEdge[0]) {
-		throw new
-			util::IllegalArgumentException("Edges do not form a triangle");
-	}
+    triEdge[0] = &startQE;
+    triEdge[1] = &triEdge[0]->lNext();
+    triEdge[2] = &triEdge[1]->lNext();
+    if (&triEdge[2]->lNext() != triEdge[0]) {
+        throw new
+            util::IllegalArgumentException("Edges do not form a triangle");
+    }
 }
 
 QuadEdgeSubdivision::QuadEdgeSubdivision(const geom::Envelope &env, double tolerance) :
-		tolerance(tolerance),
-		locator(new LastFoundQuadEdgeLocator(this))
+        tolerance(tolerance),
+        locator(new LastFoundQuadEdgeLocator(this))
 {
-	edgeCoincidenceTolerance = tolerance / EDGE_COINCIDENCE_TOL_FACTOR;
-	createFrame(env);
-	initSubdiv(startingEdges);
-	quadEdges.push_back(startingEdges[0]);
-	createdEdges.push_back(startingEdges[0]);
-	quadEdges.push_back(startingEdges[1]);
-	createdEdges.push_back(startingEdges[1]);
-	quadEdges.push_back(startingEdges[2]);
-	createdEdges.push_back(startingEdges[2]);
+    edgeCoincidenceTolerance = tolerance / EDGE_COINCIDENCE_TOL_FACTOR;
+    createFrame(env);
+    initSubdiv(startingEdges);
+    quadEdges.push_back(startingEdges[0]);
+    createdEdges.push_back(startingEdges[0]);
+    quadEdges.push_back(startingEdges[1]);
+    createdEdges.push_back(startingEdges[1]);
+    quadEdges.push_back(startingEdges[2]);
+    createdEdges.push_back(startingEdges[2]);
 }
 
 QuadEdgeSubdivision::~QuadEdgeSubdivision()
 {
-	for(QuadEdgeList::iterator iter=createdEdges.begin(); iter!=createdEdges.end(); ++iter)
-	{
-		(*iter)->free();
-		delete *iter;
-	}
+    for(QuadEdgeList::iterator iter=createdEdges.begin(); iter!=createdEdges.end(); ++iter)
+    {
+        (*iter)->free();
+        delete *iter;
+    }
 }
 
 void
 QuadEdgeSubdivision::createFrame(const geom::Envelope &env)
 {
-	double deltaX = env.getWidth();
-	double deltaY = env.getHeight();
-	double offset = 0.0;
-	if (deltaX > deltaY) {
-		offset = deltaX * 10.0;
-	} else {
-		offset = deltaY * 10.0;
-	}
+    double deltaX = env.getWidth();
+    double deltaY = env.getHeight();
+    double offset = 0.0;
+    if (deltaX > deltaY) {
+        offset = deltaX * 10.0;
+    } else {
+        offset = deltaY * 10.0;
+    }
 
-	frameVertex[0] = Vertex((env.getMaxX() + env.getMinX()) / 2.0, env
-			.getMaxY() + offset);
-	frameVertex[1] = Vertex(env.getMinX() - offset, env.getMinY() - offset);
-	frameVertex[2] = Vertex(env.getMaxX() + offset, env.getMinY() - offset);
+    frameVertex[0] = Vertex((env.getMaxX() + env.getMinX()) / 2.0, env
+            .getMaxY() + offset);
+    frameVertex[1] = Vertex(env.getMinX() - offset, env.getMinY() - offset);
+    frameVertex[2] = Vertex(env.getMaxX() + offset, env.getMinY() - offset);
 
-	frameEnv = Envelope(frameVertex[0].getCoordinate(), frameVertex[1]
-			.getCoordinate());
-	frameEnv.expandToInclude(frameVertex[2].getCoordinate());
+    frameEnv = Envelope(frameVertex[0].getCoordinate(), frameVertex[1]
+            .getCoordinate());
+    frameEnv.expandToInclude(frameVertex[2].getCoordinate());
 }
 void
 QuadEdgeSubdivision::initSubdiv(QuadEdge* initEdges[3])
 {
-	std::auto_ptr<QuadEdge> tmp_auto_ptr;
-	// build initial subdivision from frame
-	tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[0], frameVertex[1]);
-	initEdges[0] = tmp_auto_ptr.get();
-	tmp_auto_ptr.release();
+    std::auto_ptr<QuadEdge> tmp_auto_ptr;
+    // build initial subdivision from frame
+    tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[0], frameVertex[1]);
+    initEdges[0] = tmp_auto_ptr.get();
+    tmp_auto_ptr.release();
 
 
-	tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[1], frameVertex[2]);
-	initEdges[1] = tmp_auto_ptr.get();
-	tmp_auto_ptr.release();
+    tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[1], frameVertex[2]);
+    initEdges[1] = tmp_auto_ptr.get();
+    tmp_auto_ptr.release();
 
-	QuadEdge::splice(initEdges[0]->sym(), *initEdges[1]);
+    QuadEdge::splice(initEdges[0]->sym(), *initEdges[1]);
 
-	tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[2], frameVertex[0]);
-	initEdges[2] = tmp_auto_ptr.get();
-	tmp_auto_ptr.release();
+    tmp_auto_ptr = QuadEdge::makeEdge(frameVertex[2], frameVertex[0]);
+    initEdges[2] = tmp_auto_ptr.get();
+    tmp_auto_ptr.release();
 
-	QuadEdge::splice(initEdges[1]->sym(), *initEdges[2]);
-	QuadEdge::splice(initEdges[2]->sym(), *initEdges[0]);
+    QuadEdge::splice(initEdges[1]->sym(), *initEdges[2]);
+    QuadEdge::splice(initEdges[2]->sym(), *initEdges[0]);
 }
 
 QuadEdge&
 QuadEdgeSubdivision::makeEdge(const Vertex &o, const Vertex &d)
 {
-	std::auto_ptr<QuadEdge> q0 = QuadEdge::makeEdge(o, d);
-	QuadEdge *q0_ptr = q0.get();
-	q0.release();
+    std::auto_ptr<QuadEdge> q0 = QuadEdge::makeEdge(o, d);
+    QuadEdge *q0_ptr = q0.get();
+    q0.release();
 
-	createdEdges.push_back(q0_ptr);
-	quadEdges.push_back(q0_ptr);
-	return *q0_ptr;
+    createdEdges.push_back(q0_ptr);
+    quadEdges.push_back(q0_ptr);
+    return *q0_ptr;
 }
 
 QuadEdge&
 QuadEdgeSubdivision::connect(QuadEdge &a, QuadEdge &b)
 {
-	std::auto_ptr<QuadEdge> q0 = QuadEdge::connect(a, b);
-	QuadEdge *q0_ptr = q0.get();
-	q0.release();
+    std::auto_ptr<QuadEdge> q0 = QuadEdge::connect(a, b);
+    QuadEdge *q0_ptr = q0.get();
+    q0.release();
 
-	createdEdges.push_back(q0_ptr);
-	quadEdges.push_back(q0_ptr);
-	return *q0_ptr;
+    createdEdges.push_back(q0_ptr);
+    quadEdges.push_back(q0_ptr);
+    return *q0_ptr;
 }
 
 void
 QuadEdgeSubdivision::remove(QuadEdge &e)
 {
-	QuadEdge::splice(e, e.oPrev());
-	QuadEdge::splice(e.sym(), e.sym().oPrev());
+    QuadEdge::splice(e, e.oPrev());
+    QuadEdge::splice(e.sym(), e.sym().oPrev());
 
-	// this is inefficient on an ArrayList, but this method should be called infrequently
-	quadEdges.remove(&e);
+    // this is inefficient on an ArrayList, but this method should be called infrequently
+    quadEdges.remove(&e);
 
-	//mark these edges as removed
-	e.remove();
+    //mark these edges as removed
+    e.remove();
 
 }
 
 QuadEdge*
 QuadEdgeSubdivision::locateFromEdge(const Vertex &v,
-		const QuadEdge &startEdge) const
+        const QuadEdge &startEdge) const
 {
-	int iter = 0;
-	int maxIter = quadEdges.size();
+    ::geos::ignore_unused_variable_warning(startEdge);
 
-	QuadEdge *e = startingEdges[0];
+    int iter = 0;
+    int maxIter = quadEdges.size();
 
-	while (true) {
-		++iter;
-		/**
-		 * So far it has always been the case that failure to locate indicates an
-		 * invalid subdivision. So just fail completely. (An alternative would be
-		 * to perform an exhaustive search for the containing triangle, but this
-		 * would mask errors in the subdivision topology)
-		 * 
-		 * This can also happen if two vertices are located very close together,
-		 * since the orientation predicates may experience precision failures.
-		 */
-		if (iter > maxIter) {
-			throw LocateFailureException("");
-		}
+    QuadEdge *e = startingEdges[0];
 
-		if ((v.equals(e->orig())) || (v.equals(e->dest()))) {
-			break;
-		} else if (v.rightOf(*e)) {
-			e = &e->sym();
-		} else if (!v.rightOf(e->oNext())) {
-			e = &e->oNext();
-		} else if (!v.rightOf(e->dPrev())) {
-			e = &e->dPrev();
-		} else {
-			// on edge or in triangle containing edge
-			break;
-		}
-	}
-	return e;
+    for (;;)
+    {
+        ++iter;
+        /**
+         * So far it has always been the case that failure to locate indicates an
+         * invalid subdivision. So just fail completely. (An alternative would be
+         * to perform an exhaustive search for the containing triangle, but this
+         * would mask errors in the subdivision topology)
+         * 
+         * This can also happen if two vertices are located very close together,
+         * since the orientation predicates may experience precision failures.
+         */
+        if (iter > maxIter) {
+            throw LocateFailureException("");
+        }
+
+        if ((v.equals(e->orig())) || (v.equals(e->dest()))) {
+            break;
+        } else if (v.rightOf(*e)) {
+            e = &e->sym();
+        } else if (!v.rightOf(e->oNext())) {
+            e = &e->oNext();
+        } else if (!v.rightOf(e->dPrev())) {
+            e = &e->dPrev();
+        } else {
+            // on edge or in triangle containing edge
+            break;
+        }
+    }
+    return e;
 }
 
 QuadEdge*
 QuadEdgeSubdivision::locate(const Coordinate &p0, const Coordinate &p1)
 {
-	// find an edge containing one of the points
-	QuadEdge *e = locator->locate(Vertex(p0));
-	if (e == NULL)
-		return NULL;
+    // find an edge containing one of the points
+    QuadEdge *e = locator->locate(Vertex(p0));
+    if (e == NULL)
+        return NULL;
 
-	// normalize so that p0 is origin of base edge
-	QuadEdge *base = e;
-	if (e->dest().getCoordinate().equals2D(p0))
-		base = &e->sym();
-	// check all edges around origin of base edge
-	QuadEdge *locEdge = base;
-	do {
-		if (locEdge->dest().getCoordinate().equals2D(p1))
-			return locEdge;
-		locEdge = &locEdge->oNext();
-	} while (locEdge != base);
-	return NULL;
+    // normalize so that p0 is origin of base edge
+    QuadEdge *base = e;
+    if (e->dest().getCoordinate().equals2D(p0))
+        base = &e->sym();
+    // check all edges around origin of base edge
+    QuadEdge *locEdge = base;
+    do {
+        if (locEdge->dest().getCoordinate().equals2D(p1))
+            return locEdge;
+        locEdge = &locEdge->oNext();
+    } while (locEdge != base);
+    return NULL;
 }
 
 QuadEdge&
 QuadEdgeSubdivision::insertSite(const Vertex &v)
 {
-	QuadEdge *e = locate(v);
+    QuadEdge *e = locate(v);
 
-	if ((v.equals(e->orig(), tolerance)) || (v.equals(e->dest(), tolerance))) {
-		return *e; // point already in subdivision.
-	}
+    if ((v.equals(e->orig(), tolerance)) || (v.equals(e->dest(), tolerance))) {
+        return *e; // point already in subdivision.
+    }
 
-	// Connect the new point to the vertices of the containing
-	// triangle (or quadrilateral, if the new point fell on an
-	// existing edge.)
-	QuadEdge *base = &makeEdge(e->orig(), v);
-	QuadEdge::splice(*base, *e);
-	QuadEdge *startEdge = base;
-	do {
-		base = &connect(*e, base->sym());
-		e = &base->oPrev();
-	} while (&e->lNext() != startEdge);
+    // Connect the new point to the vertices of the containing
+    // triangle (or quadrilateral, if the new point fell on an
+    // existing edge.)
+    QuadEdge *base = &makeEdge(e->orig(), v);
+    QuadEdge::splice(*base, *e);
+    QuadEdge *startEdge = base;
+    do {
+        base = &connect(*e, base->sym());
+        e = &base->oPrev();
+    } while (&e->lNext() != startEdge);
 
-	return *startEdge;
+    return *startEdge;
 }
 
 bool
 QuadEdgeSubdivision::isFrameEdge(const QuadEdge &e) const
 {
-	if (isFrameVertex(e.orig()) || isFrameVertex(e.dest()))
-		return true;
-	return false;
+    if (isFrameVertex(e.orig()) || isFrameVertex(e.dest()))
+        return true;
+    return false;
 }
 
 bool
 QuadEdgeSubdivision::isFrameBorderEdge(const QuadEdge &e) const
 {
-	// check other vertex of triangle to left of edge
-	Vertex vLeftTriOther = e.lNext().dest();
-	if (isFrameVertex(vLeftTriOther))
-		return true;
-	// check other vertex of triangle to right of edge
-	Vertex vRightTriOther = e.sym().lNext().dest();
-	if (isFrameVertex(vRightTriOther))
-		return true;
+    // check other vertex of triangle to left of edge
+    Vertex vLeftTriOther = e.lNext().dest();
+    if (isFrameVertex(vLeftTriOther))
+        return true;
+    // check other vertex of triangle to right of edge
+    Vertex vRightTriOther = e.sym().lNext().dest();
+    if (isFrameVertex(vRightTriOther))
+        return true;
 
-	return false;
+    return false;
 }
 
 bool
 QuadEdgeSubdivision::isFrameVertex(const Vertex &v) const
 {
-	if (v.equals(frameVertex[0]))
-		return true;
-	if (v.equals(frameVertex[1]))
-		return true;
-	if (v.equals(frameVertex[2]))
-		return true;
-	return false;
+    if (v.equals(frameVertex[0]))
+        return true;
+    if (v.equals(frameVertex[1]))
+        return true;
+    if (v.equals(frameVertex[2]))
+        return true;
+    return false;
 }
 
 bool
 QuadEdgeSubdivision::isOnEdge(const QuadEdge &e, const Coordinate &p) const
 {
-	geom::LineSegment seg;
-	seg.setCoordinates(e.orig().getCoordinate(), e.dest().getCoordinate());
-	double dist = seg.distance(p);
-	// heuristic (hack?)
-	return dist < edgeCoincidenceTolerance;
+    geom::LineSegment seg;
+    seg.setCoordinates(e.orig().getCoordinate(), e.dest().getCoordinate());
+    double dist = seg.distance(p);
+    // heuristic (hack?)
+    return dist < edgeCoincidenceTolerance;
 }
 
 bool
 QuadEdgeSubdivision::isVertexOfEdge(const QuadEdge &e, const Vertex &v) const
 {
-	if ((v.equals(e.orig(), tolerance)) || (v.equals(e.dest(), tolerance))) {
-		return true;
-	}
-	return false;
+    if ((v.equals(e.orig(), tolerance)) || (v.equals(e.dest(), tolerance))) {
+        return true;
+    }
+    return false;
 }
 
 std::auto_ptr<QuadEdgeSubdivision::QuadEdgeList>
 QuadEdgeSubdivision::getPrimaryEdges(bool includeFrame)
 {
-	QuadEdgeList *edges = new QuadEdgeList();
-	QuadEdgeStack edgeStack;
-	QuadEdgeSet visitedEdges;
+    QuadEdgeList *edges = new QuadEdgeList();
+    QuadEdgeStack edgeStack;
+    QuadEdgeSet visitedEdges;
 
-	edgeStack.push(startingEdges[0]);
+    edgeStack.push(startingEdges[0]);
 
-	while (!edgeStack.empty())
-	{
-		QuadEdge *edge = edgeStack.top();
-		edgeStack.pop();
-		if (visitedEdges.find(edge) == visitedEdges.end())
-		{
-			QuadEdge* priQE = (QuadEdge*)&edge->getPrimary();
+    while (!edgeStack.empty())
+    {
+        QuadEdge *edge = edgeStack.top();
+        edgeStack.pop();
+        if (visitedEdges.find(edge) == visitedEdges.end())
+        {
+            QuadEdge* priQE = (QuadEdge*)&edge->getPrimary();
 
-			if (includeFrame || ! isFrameEdge(*priQE))
-				edges->push_back(priQE);
+            if (includeFrame || ! isFrameEdge(*priQE))
+                edges->push_back(priQE);
 
-			edgeStack.push(&edge->oNext());
-			edgeStack.push(&edge->sym().oNext());
+            edgeStack.push(&edge->oNext());
+            edgeStack.push(&edge->sym().oNext());
 
-			visitedEdges.insert(edge);
-			visitedEdges.insert(&edge->sym());
-		}
-	}
-	return std::auto_ptr<QuadEdgeList>(edges);
+            visitedEdges.insert(edge);
+            visitedEdges.insert(&edge->sym());
+        }
+    }
+    return std::auto_ptr<QuadEdgeList>(edges);
 }
 
 QuadEdge**
 QuadEdgeSubdivision::fetchTriangleToVisit(QuadEdge *edge,
-		QuadEdgeStack &edgeStack, bool includeFrame, QuadEdgeSet &visitedEdges)
+        QuadEdgeStack &edgeStack, bool includeFrame, QuadEdgeSet &visitedEdges)
 {
-	QuadEdge *curr = edge;
-	int edgeCount = 0;
-	bool isFrame = false;
-	do
-	{
-		triEdges[edgeCount] = curr;
+    QuadEdge *curr = edge;
+    int edgeCount = 0;
+    bool isFrame = false;
+    do
+    {
+        triEdges[edgeCount] = curr;
 
-		if (isFrameEdge(*curr))
-			isFrame = true;
+        if (isFrameEdge(*curr))
+            isFrame = true;
 
-		// push sym edges to visit next
-		QuadEdge *sym = &curr->sym();
-		if (visitedEdges.find(sym) == visitedEdges.end())
-			edgeStack.push(sym);
+        // push sym edges to visit next
+        QuadEdge *sym = &curr->sym();
+        if (visitedEdges.find(sym) == visitedEdges.end())
+            edgeStack.push(sym);
 
-		// mark this edge as visited
-		visitedEdges.insert(curr);
+        // mark this edge as visited
+        visitedEdges.insert(curr);
 
-		edgeCount++;
-		curr = &curr->lNext();
+        edgeCount++;
+        curr = &curr->lNext();
 
-	} while (curr != edge);
+    } while (curr != edge);
 
-	if (isFrame && !includeFrame)
-		return NULL;
-	return triEdges;
+    if (isFrame && !includeFrame)
+        return NULL;
+    return triEdges;
 }
 
 class
 QuadEdgeSubdivision::TriangleCoordinatesVisitor : public TriangleVisitor {
 private:
-	QuadEdgeSubdivision::TriList *triCoords;
-	CoordinateArraySequenceFactory coordSeqFact;
+    QuadEdgeSubdivision::TriList *triCoords;
+    CoordinateArraySequenceFactory coordSeqFact;
 
 public:
-	TriangleCoordinatesVisitor(QuadEdgeSubdivision::TriList *triCoords): triCoords(triCoords)
-	{
-	}
+    TriangleCoordinatesVisitor(QuadEdgeSubdivision::TriList *triCoords): triCoords(triCoords)
+    {
+    }
 
-	void visit(QuadEdge* triEdges[3])
-	{
-		geom::CoordinateSequence *coordSeq = coordSeqFact.create(4,0);
-		for (int i = 0; i < 3; i++) {
-			Vertex v = triEdges[i]->orig();
-			coordSeq->setAt(v.getCoordinate(), i);
-		}
-		coordSeq->setAt(triEdges[0]->orig().getCoordinate(), 3);
-		triCoords->push_back(coordSeq);
-	}
+    void visit(QuadEdge* triEdges[3])
+    {
+        geom::CoordinateSequence *coordSeq = coordSeqFact.create(4,0);
+        for (int i = 0; i < 3; i++) {
+            Vertex v = triEdges[i]->orig();
+            coordSeq->setAt(v.getCoordinate(), i);
+        }
+        coordSeq->setAt(triEdges[0]->orig().getCoordinate(), 3);
+        triCoords->push_back(coordSeq);
+    }
 }; 
 
 void
 QuadEdgeSubdivision::getTriangleCoordinates(QuadEdgeSubdivision::TriList* triList, bool includeFrame)
 {
-	TriangleCoordinatesVisitor visitor(triList);
-	visitTriangles((TriangleVisitor*)&visitor, includeFrame);
+    TriangleCoordinatesVisitor visitor(triList);
+    visitTriangles((TriangleVisitor*)&visitor, includeFrame);
 }
 
 void
 QuadEdgeSubdivision::visitTriangles(TriangleVisitor *triVisitor, bool includeFrame)
 {
 
-	QuadEdgeStack edgeStack;
-	edgeStack.push(startingEdges[0]);
+    QuadEdgeStack edgeStack;
+    edgeStack.push(startingEdges[0]);
 
-	QuadEdgeSet visitedEdges;
+    QuadEdgeSet visitedEdges;
 
-	while (!edgeStack.empty()) {
-		QuadEdge *edge = edgeStack.top();
-		edgeStack.pop();
-		if (visitedEdges.find(edge) == visitedEdges.end()) {
-			QuadEdge **triEdges = fetchTriangleToVisit(edge, edgeStack,
-					includeFrame, visitedEdges);
-			if (triEdges != NULL)
-				triVisitor->visit(triEdges);
-		}
-	}
+    while (!edgeStack.empty()) {
+        QuadEdge *edge = edgeStack.top();
+        edgeStack.pop();
+        if (visitedEdges.find(edge) == visitedEdges.end()) {
+            QuadEdge **triEdges = fetchTriangleToVisit(edge, edgeStack,
+                    includeFrame, visitedEdges);
+            if (triEdges != NULL)
+                triVisitor->visit(triEdges);
+        }
+    }
 }
 
 std::auto_ptr<geom::MultiLineString>
 QuadEdgeSubdivision::getEdges(const geom::GeometryFactory& geomFact)
 {
-	std::auto_ptr<QuadEdgeList> quadEdges(getPrimaryEdges(false));
-	std::vector<Geometry *> edges(quadEdges->size());
-	const CoordinateSequenceFactory *coordSeqFact = geomFact.getCoordinateSequenceFactory();
-	int i = 0;
-	for (QuadEdgeSubdivision::QuadEdgeList::iterator it = quadEdges->begin(); it != quadEdges->end(); ++it)
-	{
-		QuadEdge *qe = *it;
-		CoordinateSequence *coordSeq = coordSeqFact->create((std::vector<geom::Coordinate>*)NULL);;
+    std::auto_ptr<QuadEdgeList> quadEdges(getPrimaryEdges(false));
+    std::vector<Geometry *> edges(quadEdges->size());
+    const CoordinateSequenceFactory *coordSeqFact = geomFact.getCoordinateSequenceFactory();
+    int i = 0;
+    for (QuadEdgeSubdivision::QuadEdgeList::iterator it = quadEdges->begin(); it != quadEdges->end(); ++it)
+    {
+        QuadEdge *qe = *it;
+        CoordinateSequence *coordSeq = coordSeqFact->create((std::vector<geom::Coordinate>*)NULL);;
 
-		coordSeq->add(qe->orig().getCoordinate());
-		coordSeq->add(qe->dest().getCoordinate());
+        coordSeq->add(qe->orig().getCoordinate());
+        coordSeq->add(qe->dest().getCoordinate());
 
-		edges[i++] = static_cast<Geometry*>(geomFact.createLineString(*coordSeq));
+        edges[i++] = static_cast<Geometry*>(geomFact.createLineString(*coordSeq));
 
-		delete coordSeq;
-	}
+        delete coordSeq;
+    }
 
-	geom::MultiLineString* result = geomFact.createMultiLineString(edges);
+    geom::MultiLineString* result = geomFact.createMultiLineString(edges);
 
-	for(std::vector<Geometry*>::iterator it=edges.begin(); it!=edges.end(); ++it)
-		delete *it;
+    for(std::vector<Geometry*>::iterator it=edges.begin(); it!=edges.end(); ++it)
+        delete *it;
 
-	return std::auto_ptr<MultiLineString>(result);
+    return std::auto_ptr<MultiLineString>(result);
 }
 
 std::auto_ptr<GeometryCollection>
 QuadEdgeSubdivision::getTriangles( const GeometryFactory &geomFact)
 {
-	TriList triPtsList;
-	getTriangleCoordinates(&triPtsList, false);
-	std::vector<Geometry*> tris;
+    TriList triPtsList;
+    getTriangleCoordinates(&triPtsList, false);
+    std::vector<Geometry*> tris;
 
-	for(TriList::const_iterator it = triPtsList.begin();
-			it != triPtsList.end(); ++it)
-	{
-		CoordinateSequence *coordSeq = *it;
-		Polygon *tri = geomFact.createPolygon(
-				geomFact.createLinearRing(coordSeq), NULL);
-		tris.push_back(static_cast<Geometry*>(tri));
-	}
-	GeometryCollection* ret =  geomFact.createGeometryCollection(tris);
+    for(TriList::const_iterator it = triPtsList.begin();
+            it != triPtsList.end(); ++it)
+    {
+        CoordinateSequence *coordSeq = *it;
+        Polygon *tri = geomFact.createPolygon(
+                geomFact.createLinearRing(coordSeq), NULL);
+        tris.push_back(static_cast<Geometry*>(tri));
+    }
+    GeometryCollection* ret =  geomFact.createGeometryCollection(tris);
 
-	//release memory
-	for(std::vector<Geometry*>::iterator it=tris.begin(); it!=tris.end(); ++it)
-		delete *it;
-	tris.clear();
+    //release memory
+    for(std::vector<Geometry*>::iterator it=tris.begin(); it!=tris.end(); ++it)
+        delete *it;
+    tris.clear();
 
-	return std::auto_ptr<GeometryCollection>(ret);
+    return std::auto_ptr<GeometryCollection>(ret);
 }
 
 } //namespace geos.triangulate.quadedge



More information about the geos-commits mailing list