/********************************************************************** * $Id: MonotoneChainBuilder.cpp 2109 2008-01-18 00:35:10Z benjubb $ * * 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 #include #include #include #include #include #ifndef GEOS_DEBUG #define GEOS_DEBUG 0 #endif #if GEOS_DEBUG #include #endif using namespace std; using namespace geos::geomgraph; using namespace geos::geom; namespace geos { namespace index { // geos.index namespace chain { // geos.index.chain /* static public */ vector* MonotoneChainBuilder::getChains(const CoordinateSequence* pts, void* context) { vector *mcList=new vector(); getChains(pts, context, *mcList); return mcList; } /* static public */ void MonotoneChainBuilder::getChains(const CoordinateSequence* pts, void* context, vector& mcList) { vector startIndex; getChainStartIndices(pts, startIndex); size_t nindexes=startIndex.size(); if ( nindexes ) { size_t n=nindexes-1; for(size_t i=0; i& startIndexList) { // find the startpoint (and endpoints) of all monotone chains // in this edge int start=0; startIndexList.push_back(start); const std::size_t n=pts->getSize() - 1; do { int last=findChainEnd(pts, start); startIndexList.push_back(last); start=last; } while (static_cast(start) < n); } /** * @return the index of the last point in the monotone chain starting * at start. */ int MonotoneChainBuilder::findChainEnd(const CoordinateSequence *pts, int start) { std::size_t npts = pts->getSize(); // skip any zero-length segments at start of sequence while ( pts->getAt( start).equals2D( pts->getAt( start + 1) ) ) if ( ++start >= ( npts - 1 ) ) // bail if there are no non-zero-length segments return npts - 1; // determine quadrant for chain int chainQuad=Quadrant::quadrant(pts->getAt(start),pts->getAt(start + 1)); std::size_t last=start+1; while (last < npts) { // skip a zero-length segnments if (! pts->getAt( last - 1).equals2D( pts->getAt( last) ) ) { // compute quadrant for next possible segment in chain int quad=Quadrant::quadrant(pts->getAt(last-1),pts->getAt(last)); if (quad!=chainQuad) break; } last++; } #if GEOS_DEBUG std::cerr<<"MonotoneChainBuilder::findChainEnd() returning"<(last - 1); } } // namespace geos.index.chain } // namespace geos.index } // namespace geos /********************************************************************** * $Log$ * Revision 1.25 2006/06/12 11:29:23 strk * unsigned int => size_t * * Revision 1.24 2006/03/23 13:31:58 strk * Fixed to allow build with GEOS_DEBUG * * Revision 1.23 2006/03/22 18:12:32 strk * indexChain.h header split. * **********************************************************************/