Skip to content

Commit

Permalink
Use reduced precision also in QgsGeos::isEqual
Browse files Browse the repository at this point in the history
  • Loading branch information
manisandro committed Sep 21, 2015
1 parent 5f78d1c commit 0a99a6c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 48 deletions.
86 changes: 38 additions & 48 deletions src/core/geometry/qgsgeos.cpp
Expand Up @@ -103,6 +103,7 @@ class GEOSGeomScopedPtr
GEOSGeomScopedPtr( GEOSGeometry* geom = 0 ) : mGeom( geom ) {}
~GEOSGeomScopedPtr() { GEOSGeom_destroy_r( geosinit.ctxt, mGeom ); }
GEOSGeometry* get() const { return mGeom; }
operator bool() const { return mGeom != 0; }
void reset( GEOSGeometry* geom )
{
GEOSGeom_destroy_r( geosinit.ctxt, mGeom );
Expand Down Expand Up @@ -135,6 +136,18 @@ QgsGeos::~QgsGeos()
#endif
}

inline GEOSGeometry* QgsGeos::getReducedGeometry( GEOSGeometry* geom ) const
{
#ifdef HAVE_GEOS_CPP
//reduce precision
GEOSGeometry* reduced = GEOSGeometryPrecisionReducer_reduce( mPrecisionReducer, geom );
GEOSGeom_destroy_r( geosinit.ctxt, geom );
return reduced;
#else
return geom;
#endif
}

void QgsGeos::geometryChanged()
{
GEOSGeom_destroy_r( geosinit.ctxt, mGeos );
Expand Down Expand Up @@ -195,7 +208,7 @@ QgsAbstractGeometryV2* QgsGeos::combine( const QList< const QgsAbstractGeometryV
geosGeometries.resize( geomList.size() );
for ( int i = 0; i < geomList.size(); ++i )
{
geosGeometries[i] = asGeos( geomList.at( i ) );
geosGeometries[i] = getReducedGeometry( asGeos( geomList.at( i ) ) );
}

GEOSGeometry* geomUnion = 0;
Expand Down Expand Up @@ -1050,40 +1063,28 @@ QgsAbstractGeometryV2* QgsGeos::overlay( const QgsAbstractGeometryV2& geom, Over
return 0;
}

GEOSGeometry* gG = asGeos( &geom );
if ( !gG )
GEOSGeomScopedPtr geosGeom = getReducedGeometry( asGeos( &geom ) );
if ( !geosGeom )
{
return 0;
}

#ifdef HAVE_GEOS_CPP
GEOSGeomScopedPtr geosGeom;
geosGeom.reset( gG );

//reduce precision
GEOSGeomScopedPtr pg2;
pg2.reset( GEOSGeometryPrecisionReducer_reduce( mPrecisionReducer, geosGeom.get() ) );
#else
GEOSGeomScopedPtr pg2;
pg2.reset( gG );
#endif

try
{
GEOSGeomScopedPtr opGeom;
switch ( op )
{
case INTERSECTION:
opGeom.reset( GEOSIntersection_r( geosinit.ctxt, mGeos, pg2.get() ) );
opGeom.reset( GEOSIntersection_r( geosinit.ctxt, mGeos, geosGeom.get() ) );
break;
case DIFFERENCE:
opGeom.reset( GEOSDifference_r( geosinit.ctxt, mGeos, pg2.get() ) );
opGeom.reset( GEOSDifference_r( geosinit.ctxt, mGeos, geosGeom.get() ) );
break;
case UNION:
opGeom.reset( GEOSUnion_r( geosinit.ctxt, mGeos, pg2.get() ) );
opGeom.reset( GEOSUnion_r( geosinit.ctxt, mGeos, geosGeom.get() ) );
break;
case SYMDIFFERENCE:
opGeom.reset( GEOSSymDifference_r( geosinit.ctxt, mGeos, pg2.get() ) );
opGeom.reset( GEOSSymDifference_r( geosinit.ctxt, mGeos, geosGeom.get() ) );
break;
default: //unknown op
return 0;
Expand All @@ -1108,21 +1109,11 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
return false;
}

GEOSGeometry* gG = asGeos( &geom );
if ( !gG )
GEOSGeomScopedPtr geosGeom = getReducedGeometry( asGeos( &geom ) );
if ( !geosGeom )
{
return false;
}
#ifdef HAVE_GEOS_CPP
GEOSGeomScopedPtr geosGeom;
geosGeom.reset( gG );

GEOSGeomScopedPtr pg2;
pg2.reset( GEOSGeometryPrecisionReducer_reduce( mPrecisionReducer, geosGeom.get() ) );
#else
GEOSGeomScopedPtr pg2;
pg2.reset( gG );
#endif

bool result = false;
try
Expand All @@ -1132,25 +1123,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
switch ( r )
{
case INTERSECTS:
result = ( GEOSPreparedIntersects_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedIntersects_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case TOUCHES:
result = ( GEOSPreparedTouches_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedTouches_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case CROSSES:
result = ( GEOSPreparedCrosses_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedCrosses_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case WITHIN:
result = ( GEOSPreparedWithin_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedWithin_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case CONTAINS:
result = ( GEOSPreparedContains_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedContains_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case DISJOINT:
result = ( GEOSPreparedDisjoint_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedDisjoint_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
case OVERLAPS:
result = ( GEOSPreparedOverlaps_r( geosinit.ctxt, mGeosPrepared, pg2.get() ) == 1 );
result = ( GEOSPreparedOverlaps_r( geosinit.ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
break;
default:
return false;
Expand All @@ -1161,25 +1152,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
switch ( r )
{
case INTERSECTS:
result = ( GEOSIntersects_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSIntersects_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case TOUCHES:
result = ( GEOSTouches_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSTouches_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case CROSSES:
result = ( GEOSCrosses_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSCrosses_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case WITHIN:
result = ( GEOSWithin_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSWithin_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case CONTAINS:
result = ( GEOSContains_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSContains_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case DISJOINT:
result = ( GEOSDisjoint_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSDisjoint_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
case OVERLAPS:
result = ( GEOSOverlaps_r( geosinit.ctxt, mGeos, pg2.get() ) == 1 );
result = ( GEOSOverlaps_r( geosinit.ctxt, mGeos, geosGeom.get() ) == 1 );
break;
default:
return false;
Expand Down Expand Up @@ -1375,13 +1366,12 @@ bool QgsGeos::isEqual( const QgsAbstractGeometryV2& geom, QString* errorMsg ) co

try
{
GEOSGeometry* geosGeom = asGeos( &geom );
GEOSGeomScopedPtr geosGeom = getReducedGeometry( asGeos( &geom ) );
if ( !geosGeom )
{
return false;
}
bool equal = GEOSEquals_r( geosinit.ctxt, mGeos, geosGeom );
GEOSGeom_destroy_r( geosinit.ctxt, geosGeom );
bool equal = GEOSEquals_r( geosinit.ctxt, mGeos, geosGeom.get() );
return equal;
}
CATCH_GEOS_WITH_ERRMSG( false );
Expand Down
3 changes: 3 additions & 0 deletions src/core/geometry/qgsgeos.h
Expand Up @@ -144,6 +144,9 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
static int lineContainedInLine( const GEOSGeometry* line1, const GEOSGeometry* line2 );
static int pointContainedInLine( const GEOSGeometry* point, const GEOSGeometry* line );
static int geomDigits( const GEOSGeometry* geom );

private:
inline GEOSGeometry *getReducedGeometry( GEOSGeometry* geom ) const;
};

/// @cond
Expand Down

0 comments on commit 0a99a6c

Please sign in to comment.