Skip to content
Permalink
Browse files

Use reduced precision also in QgsGeos::isEqual

  • Loading branch information
manisandro committed Sep 21, 2015
1 parent 5f78d1c commit 0a99a6c0f55d68bde03b0ce5db15c890ec05c2ee
Showing with 41 additions and 48 deletions.
  1. +38 −48 src/core/geometry/qgsgeos.cpp
  2. +3 −0 src/core/geometry/qgsgeos.h
@@ -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 );
@@ -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 );
@@ -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;
@@ -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;
@@ -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
@@ -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;
@@ -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;
@@ -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 );
@@ -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

0 comments on commit 0a99a6c

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