@@ -103,6 +103,7 @@ class GEOSGeomScopedPtr
103
103
GEOSGeomScopedPtr ( GEOSGeometry* geom = 0 ) : mGeom ( geom ) {}
104
104
~GEOSGeomScopedPtr () { GEOSGeom_destroy_r ( geosinit.ctxt , mGeom ); }
105
105
GEOSGeometry* get () const { return mGeom ; }
106
+ operator bool () const { return mGeom != 0 ; }
106
107
void reset ( GEOSGeometry* geom )
107
108
{
108
109
GEOSGeom_destroy_r ( geosinit.ctxt , mGeom );
@@ -135,6 +136,18 @@ QgsGeos::~QgsGeos()
135
136
#endif
136
137
}
137
138
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
+
138
151
void QgsGeos::geometryChanged ()
139
152
{
140
153
GEOSGeom_destroy_r ( geosinit.ctxt , mGeos );
@@ -195,7 +208,7 @@ QgsAbstractGeometryV2* QgsGeos::combine( const QList< const QgsAbstractGeometryV
195
208
geosGeometries.resize ( geomList.size () );
196
209
for ( int i = 0 ; i < geomList.size (); ++i )
197
210
{
198
- geosGeometries[i] = asGeos ( geomList.at ( i ) );
211
+ geosGeometries[i] = getReducedGeometry ( asGeos ( geomList.at ( i ) ) );
199
212
}
200
213
201
214
GEOSGeometry* geomUnion = 0 ;
@@ -1050,40 +1063,28 @@ QgsAbstractGeometryV2* QgsGeos::overlay( const QgsAbstractGeometryV2& geom, Over
1050
1063
return 0 ;
1051
1064
}
1052
1065
1053
- GEOSGeometry* gG = asGeos ( &geom );
1054
- if ( !gG )
1066
+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
1067
+ if ( !geosGeom )
1055
1068
{
1056
1069
return 0 ;
1057
1070
}
1058
1071
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
-
1071
1072
try
1072
1073
{
1073
1074
GEOSGeomScopedPtr opGeom;
1074
1075
switch ( op )
1075
1076
{
1076
1077
case INTERSECTION:
1077
- opGeom.reset ( GEOSIntersection_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1078
+ opGeom.reset ( GEOSIntersection_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
1078
1079
break ;
1079
1080
case DIFFERENCE:
1080
- opGeom.reset ( GEOSDifference_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1081
+ opGeom.reset ( GEOSDifference_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
1081
1082
break ;
1082
1083
case UNION:
1083
- opGeom.reset ( GEOSUnion_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1084
+ opGeom.reset ( GEOSUnion_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
1084
1085
break ;
1085
1086
case SYMDIFFERENCE:
1086
- opGeom.reset ( GEOSSymDifference_r ( geosinit.ctxt , mGeos , pg2 .get () ) );
1087
+ opGeom.reset ( GEOSSymDifference_r ( geosinit.ctxt , mGeos , geosGeom .get () ) );
1087
1088
break ;
1088
1089
default : // unknown op
1089
1090
return 0 ;
@@ -1108,21 +1109,11 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
1108
1109
return false ;
1109
1110
}
1110
1111
1111
- GEOSGeometry* gG = asGeos ( &geom );
1112
- if ( !gG )
1112
+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
1113
+ if ( !geosGeom )
1113
1114
{
1114
1115
return false ;
1115
1116
}
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
1126
1117
1127
1118
bool result = false ;
1128
1119
try
@@ -1132,25 +1123,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
1132
1123
switch ( r )
1133
1124
{
1134
1125
case INTERSECTS:
1135
- result = ( GEOSPreparedIntersects_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1126
+ result = ( GEOSPreparedIntersects_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1136
1127
break ;
1137
1128
case TOUCHES:
1138
- result = ( GEOSPreparedTouches_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1129
+ result = ( GEOSPreparedTouches_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1139
1130
break ;
1140
1131
case CROSSES:
1141
- result = ( GEOSPreparedCrosses_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1132
+ result = ( GEOSPreparedCrosses_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1142
1133
break ;
1143
1134
case WITHIN:
1144
- result = ( GEOSPreparedWithin_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1135
+ result = ( GEOSPreparedWithin_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1145
1136
break ;
1146
1137
case CONTAINS:
1147
- result = ( GEOSPreparedContains_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1138
+ result = ( GEOSPreparedContains_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1148
1139
break ;
1149
1140
case DISJOINT:
1150
- result = ( GEOSPreparedDisjoint_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1141
+ result = ( GEOSPreparedDisjoint_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1151
1142
break ;
1152
1143
case OVERLAPS:
1153
- result = ( GEOSPreparedOverlaps_r ( geosinit.ctxt , mGeosPrepared , pg2 .get () ) == 1 );
1144
+ result = ( GEOSPreparedOverlaps_r ( geosinit.ctxt , mGeosPrepared , geosGeom .get () ) == 1 );
1154
1145
break ;
1155
1146
default :
1156
1147
return false ;
@@ -1161,25 +1152,25 @@ bool QgsGeos::relation( const QgsAbstractGeometryV2& geom, Relation r, QString*
1161
1152
switch ( r )
1162
1153
{
1163
1154
case INTERSECTS:
1164
- result = ( GEOSIntersects_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1155
+ result = ( GEOSIntersects_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1165
1156
break ;
1166
1157
case TOUCHES:
1167
- result = ( GEOSTouches_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1158
+ result = ( GEOSTouches_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1168
1159
break ;
1169
1160
case CROSSES:
1170
- result = ( GEOSCrosses_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1161
+ result = ( GEOSCrosses_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1171
1162
break ;
1172
1163
case WITHIN:
1173
- result = ( GEOSWithin_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1164
+ result = ( GEOSWithin_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1174
1165
break ;
1175
1166
case CONTAINS:
1176
- result = ( GEOSContains_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1167
+ result = ( GEOSContains_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1177
1168
break ;
1178
1169
case DISJOINT:
1179
- result = ( GEOSDisjoint_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1170
+ result = ( GEOSDisjoint_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1180
1171
break ;
1181
1172
case OVERLAPS:
1182
- result = ( GEOSOverlaps_r ( geosinit.ctxt , mGeos , pg2 .get () ) == 1 );
1173
+ result = ( GEOSOverlaps_r ( geosinit.ctxt , mGeos , geosGeom .get () ) == 1 );
1183
1174
break ;
1184
1175
default :
1185
1176
return false ;
@@ -1375,13 +1366,12 @@ bool QgsGeos::isEqual( const QgsAbstractGeometryV2& geom, QString* errorMsg ) co
1375
1366
1376
1367
try
1377
1368
{
1378
- GEOSGeometry* geosGeom = asGeos ( &geom );
1369
+ GEOSGeomScopedPtr geosGeom = getReducedGeometry ( asGeos ( &geom ) );
1379
1370
if ( !geosGeom )
1380
1371
{
1381
1372
return false ;
1382
1373
}
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 () );
1385
1375
return equal;
1386
1376
}
1387
1377
CATCH_GEOS_WITH_ERRMSG ( false );
0 commit comments