Skip to content
Permalink
Browse files

pal: replace polygon validity check with check from GEOS. Much faster…

…. And don't check it twice, that's not necessary.

git-svn-id: http://svn.osgeo.org/qgis/branches/symbology-ng-branch@11008 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder
wonder committed Jul 2, 2009
1 parent 2ba94c2 commit 315c22d49c1d7478f5f46bdeb2659fd291e557f3
Showing with 14 additions and 92 deletions.
  1. +1 −1 src/core/pal/feature.cpp
  2. +2 −1 src/core/pal/layer.cpp
  3. +1 −1 src/core/pal/pointset.h
  4. +9 −88 src/core/pal/util.cpp
  5. +1 −1 src/core/pal/util.h
@@ -859,7 +859,7 @@ namespace pal
{
//std::cout << "fetch feat " << layer->name << "/" << uid << std::endl;
the_geom = userGeom->getGeosGeometry();
LinkedList<Feat*> *feats = splitGeom( the_geom, this->uid );
LinkedList<Feat*> *feats = splitGeom( the_geom, this->uid, false );
int id = 0;
while ( feats->size() > 0 )
{
@@ -324,7 +324,8 @@ void Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
/* Split MULTI GEOM and Collection in simple geometries*/
GEOSGeometry *the_geom = userGeom->getGeosGeometry();

LinkedList<Feat*> *finalQueue = splitGeom( the_geom, geom_id );
// also check whether the geometry is valid
LinkedList<Feat*> *finalQueue = splitGeom( the_geom, geom_id, true );

int nGeom = finalQueue->size();
int part = 0;
@@ -103,7 +103,7 @@ namespace pal
friend bool obstacleCallback( PointSet *feat, void *ctx );
friend bool extractFeatCallback( Feature*, void* );
friend void extractXYCoord( Feat *f );
friend LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id );
friend LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id, bool check_valid );
friend void releaseAllInIndex( RTree<PointSet*, double, 2, double> *obstacles );
friend bool releaseCallback( PointSet *pset, void *ctx );
friend bool filteringCallback( PointSet*, void* );
@@ -443,10 +443,9 @@ namespace pal



LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id )
LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id, bool check_valid )
{
LinkedList <Feat*> *fCoordQueue = new LinkedList<Feat*> ( ptrFeatCompare );
LinkedList <Feat*> *finalQueue = new LinkedList<Feat*> ( ptrFeatCompare );

LinkedList <const GEOSGeometry*> *simpleGeometries = unmulti( the_geom );

@@ -464,6 +463,13 @@ namespace pal
while ( simpleGeometries->size() > 0 )
{
geom = simpleGeometries->pop_front();

// ignore invalid geometries (e.g. polygons with self-intersecting rings)
if (check_valid && GEOSisValid( geom ) != 1) // 0=invalid, 1=valid, 2=exception
{
continue;
}

//std::cout << " split->typeid : " << geom->getGeometryTypeId() << std::endl;
switch ( GEOSGeomTypeId( geom ) )
{
@@ -538,92 +544,7 @@ namespace pal

delete simpleGeometries;

cX = 0.0;
cY = 0.0;

while ( fCoordQueue->size() > 0 )
{
f = fCoordQueue->pop_front();

if ( f->type == GEOS_POLYGON )
{
#ifdef _DEBUG_FULL_
std::cout << "New feature coordinates:" << std::endl;
for ( i = 0;i < f->nbPoints;i++ )
std::cout << f->x[i] << ";" << f->y[i] << std::endl;
#endif

// Butterfly detector
//
// 3____0
// \ /
// \/ <--- not allowed
// /\
// 1/__\2
//
// 1____0
// \ /
// 2\/5 <--- allowed
// /\
// 3/__\4
//
pt_a = -1;
pt_b = -1;
for ( i = 0;i < f->nbPoints - 2;i++ )
{
j = i + 1;
j2 = ( j + 1 ) % f->nbPoints;
for ( k = i + 2;k < f->nbPoints - ( i == 0 );k++ )
{
l = ( k + 1 ) % f->nbPoints;
l2 = ( l + 1 ) % f->nbPoints;

//std::cout << " " << i << "->" << j << " " << k << "->" << l << std::endl;
if ( computeSegIntersectionExt( f->x[i], f->y[i],
f->x[j], f->y[j],
f->x[j2], f->y[j2],
f->x[k], f->y[k],
f->x[l], f->y[l],
f->x[l2], f->y[l2],
&tmpX, &tmpY ) )
{
#ifdef _DEBUG_FULL_
std::cout << i << "->" << j << " intersect " << k << "->" << l << std::endl;
#endif
pt_a = i;
pt_b = k;
cX = tmpX;
cY = tmpY;
i = k = f->nbPoints;
}
}
}

if ( pt_a == -1 && pt_b == -1 )
{
finalQueue->push_back( f );
}
else
{
//fCoordQueue->push_back(splitButterflyPolygon (f, (pt_a+1)%f->nbPoints, (pt_b+1)%f->nbPoints, cX, cY));
//fCoordQueue->push_back(splitButterflyPolygon (f, (pt_b+1)%f->nbPoints, (pt_a+1)%f->nbPoints, cX, cY));
for ( i = 0;i < f->nbHoles;i++ )
delete f->holes[i];
delete f->holes;
delete[] f->x;
delete[] f->y;
delete f;
}
}
else
{
finalQueue->push_back( f );
}

}
delete fCoordQueue;
//delete the_geom;
return finalQueue;
return fCoordQueue;
}

} // namespace
@@ -82,7 +82,7 @@ namespace pal
/**
* \brief split GEOS geom (multilinestring, multipoint, multipolygon) => (point, linestring, polygone)
*/
LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id );
LinkedList<Feat*> * splitGeom( GEOSGeometry *the_geom, const char *geom_id, bool check_valid );

typedef struct _feats
{

0 comments on commit 315c22d

Please sign in to comment.
You can’t perform that action at this time.