@@ -103,6 +103,7 @@ class GEOSGeomScopedPtr
103103 GEOSGeomScopedPtr ( GEOSGeometry* geom = 0 ) : mGeom ( geom ) {}
104104 ~GEOSGeomScopedPtr () { GEOSGeom_destroy_r ( geosinit.ctxt , mGeom ); }
105105 GEOSGeometry* get () const { return mGeom ; }
106+ operator bool () const { return mGeom != 0 ; }
106107 void reset ( GEOSGeometry* geom )
107108 {
108109 GEOSGeom_destroy_r ( geosinit.ctxt , mGeom );
@@ -135,6 +136,18 @@ QgsGeos::~QgsGeos()
135136#endif
136137}
137138
139+ inline GEOSGeometry* QgsGeos::getReducedGeometry ( GEOSGeometry* geom ) const
140+ {
141+ #ifdef HAVE_GEOS_CPP
142+ // reduce precision
143+ GEOSGeometry* reduced = GEOSGeometryPrecisionReducer_reduce ( mPrecisionReducer , geom );
144+ GEOSGeom_destroy_r ( geosinit.ctxt , geom );
145+ return reduced;
146+ #else
147+ return geom;
148+ #endif
149+ }
150+
138151void QgsGeos::geometryChanged ()
139152{
140153 GEOSGeom_destroy_r ( geosinit.ctxt , mGeos );
@@ -195,7 +208,7 @@ QgsAbstractGeometryV2* QgsGeos::combine( const QList< const QgsAbstractGeometryV
195208 geosGeometries.resize ( geomList.size () );
196209 for ( int i = 0 ; i < geomList.size (); ++i )
197210 {
198- geosGeometries[i] = asGeos ( geomList.at ( i ) );
211+ geosGeometries[i] = getReducedGeometry ( asGeos ( geomList.at ( i ) ) );
199212 }
200213
201214 GEOSGeometry* geomUnion = 0 ;
@@ -1050,40 +1063,28 @@ QgsAbstractGeometryV2* QgsGeos::overlay( const QgsAbstractGeometryV2& geom, Over
10501063 return 0 ;
10511064 }
10521065
1053- GEOSGeometry* gG = asGeos ( &geom );
1054- if ( !gG )
1066+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
1067+ if ( !geosGeom )
10551068 {
10561069 return 0 ;
10571070 }
10581071
1059- #ifdef HAVE_GEOS_CPP
1060- GEOSGeomScopedPtr geosGeom;
1061- geosGeom.reset ( gG );
1062-
1063- // reduce precision
1064- GEOSGeomScopedPtr pg2;
1065- pg2.reset ( GEOSGeometryPrecisionReducer_reduce ( mPrecisionReducer , geosGeom.get () ) );
1066- #else
1067- GEOSGeomScopedPtr pg2;
1068- pg2.reset ( gG );
1069- #endif
1070-
10711072 try
10721073 {
10731074 GEOSGeomScopedPtr opGeom;
10741075 switch ( op )
10751076 {
10761077 case INTERSECTION:
1077- opGeom.reset ( GEOSIntersection_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1078+ opGeom.reset ( GEOSIntersection_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
10781079 break ;
10791080 case DIFFERENCE:
1080- opGeom.reset ( GEOSDifference_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1081+ opGeom.reset ( GEOSDifference_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
10811082 break ;
10821083 case UNION:
1083- opGeom.reset ( GEOSUnion_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1084+ opGeom.reset ( GEOSUnion_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
10841085 break ;
10851086 case SYMDIFFERENCE:
1086- opGeom.reset ( GEOSSymDifference_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1087+ opGeom.reset ( GEOSSymDifference_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
10871088 break ;
10881089 default : // unknown op
10891090 return 0 ;
@@ -1108,21 +1109,11 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
11081109 return false ;
11091110 }
11101111
1111- GEOSGeometry* gG = asGeos ( &geom );
1112- if ( !gG )
1112+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
1113+ if ( !geosGeom )
11131114 {
11141115 return false ;
11151116 }
1116- #ifdef HAVE_GEOS_CPP
1117- GEOSGeomScopedPtr geosGeom;
1118- geosGeom.reset ( gG );
1119-
1120- GEOSGeomScopedPtr pg2;
1121- pg2.reset ( GEOSGeometryPrecisionReducer_reduce ( mPrecisionReducer , geosGeom.get () ) );
1122- #else
1123- GEOSGeomScopedPtr pg2;
1124- pg2.reset ( gG );
1125- #endif
11261117
11271118 bool result = false ;
11281119 try
@@ -1132,25 +1123,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
11321123 switch ( r )
11331124 {
11341125 case INTERSECTS:
1135- result = ( GEOSPreparedIntersects_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1126+ result = ( GEOSPreparedIntersects_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11361127 break ;
11371128 case TOUCHES:
1138- result = ( GEOSPreparedTouches_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1129+ result = ( GEOSPreparedTouches_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11391130 break ;
11401131 case CROSSES:
1141- result = ( GEOSPreparedCrosses_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1132+ result = ( GEOSPreparedCrosses_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11421133 break ;
11431134 case WITHIN:
1144- result = ( GEOSPreparedWithin_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1135+ result = ( GEOSPreparedWithin_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11451136 break ;
11461137 case CONTAINS:
1147- result = ( GEOSPreparedContains_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1138+ result = ( GEOSPreparedContains_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11481139 break ;
11491140 case DISJOINT:
1150- result = ( GEOSPreparedDisjoint_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1141+ result = ( GEOSPreparedDisjoint_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11511142 break ;
11521143 case OVERLAPS:
1153- result = ( GEOSPreparedOverlaps_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1144+ result = ( GEOSPreparedOverlaps_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
11541145 break ;
11551146 default :
11561147 return false ;
@@ -1161,25 +1152,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
11611152 switch ( r )
11621153 {
11631154 case INTERSECTS:
1164- result = ( GEOSIntersects_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1155+ result = ( GEOSIntersects_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11651156 break ;
11661157 case TOUCHES:
1167- result = ( GEOSTouches_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1158+ result = ( GEOSTouches_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11681159 break ;
11691160 case CROSSES:
1170- result = ( GEOSCrosses_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1161+ result = ( GEOSCrosses_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11711162 break ;
11721163 case WITHIN:
1173- result = ( GEOSWithin_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1164+ result = ( GEOSWithin_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11741165 break ;
11751166 case CONTAINS:
1176- result = ( GEOSContains_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1167+ result = ( GEOSContains_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11771168 break ;
11781169 case DISJOINT:
1179- result = ( GEOSDisjoint_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1170+ result = ( GEOSDisjoint_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11801171 break ;
11811172 case OVERLAPS:
1182- result = ( GEOSOverlaps_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1173+ result = ( GEOSOverlaps_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
11831174 break ;
11841175 default :
11851176 return false ;
@@ -1375,13 +1366,12 @@ bool QgsGeos::isEqual( const QgsAbstractGeometryV2& geom, QString* errorMsg ) co
13751366
13761367 try
13771368 {
1378- GEOSGeometry* geosGeom = asGeos ( &geom );
1369+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
13791370 if ( !geosGeom )
13801371 {
13811372 return false ;
13821373 }
1383- bool equal = GEOSEquals_r ( geosinit.ctxt , mGeos , geosGeom );
1384- GEOSGeom_destroy_r ( geosinit.ctxt , geosGeom );
1374+ bool equal = GEOSEquals_r ( geosinit.ctxt , mGeos , geosGeom.get () );
13851375 return equal;
13861376 }
13871377 CATCH_GEOS_WITH_ERRMSG ( false );
0 commit comments