@@ -202,6 +202,10 @@ bool QgsInvertedPolygonRenderer::renderFeature( QgsFeature& feature, QgsRenderCo
202
202
geom.reset ( geom->buffer ( 0 , 0 ) );
203
203
}
204
204
}
205
+
206
+ if ( !geom )
207
+ return false ; // do not let invalid geometries sneak in!
208
+
205
209
// add the geometry to the list of geometries for this feature
206
210
cFeat.geometries .append ( geom.take () );
207
211
@@ -221,18 +225,15 @@ void QgsInvertedPolygonRenderer::stopRender( QgsRenderContext& context )
221
225
222
226
for ( FeatureCategoryVector::iterator cit = mFeaturesCategories .begin (); cit != mFeaturesCategories .end (); ++cit )
223
227
{
224
- QgsFeature& feat = cit->feature ;
228
+ QgsFeature feat = cit->feature ; // just a copy, so that we do not accumulate geometries again
225
229
if ( mPreprocessingEnabled )
226
230
{
227
231
// compute the unary union on the polygons
228
232
QScopedPointer<QgsGeometry> unioned ( QgsGeometry::unaryUnion ( cit->geometries ) );
229
233
// compute the difference with the extent
230
234
QScopedPointer<QgsGeometry> rect ( QgsGeometry::fromPolygon ( mExtentPolygon ) );
231
- QgsGeometry *final = rect->difference ( const_cast <QgsGeometry*>(unioned.data ()) );
232
- if ( final )
233
- {
234
- feat.setGeometry ( final );
235
- }
235
+ QgsGeometry *final = rect->difference ( const_cast <QgsGeometry*>( unioned.data () ) );
236
+ feat.setGeometry ( final );
236
237
}
237
238
else
238
239
{
@@ -248,7 +249,7 @@ void QgsInvertedPolygonRenderer::stopRender( QgsRenderContext& context )
248
249
// operations do not need geometries to be valid
249
250
QgsMultiPolygon finalMulti;
250
251
finalMulti.append ( mExtentPolygon );
251
- foreach ( QgsGeometry* geom, cit->geometries )
252
+ foreach ( QgsGeometry* geom, cit->geometries )
252
253
{
253
254
QgsMultiPolygon multi;
254
255
if (( geom->wkbType () == QGis::WKBPolygon ) ||
@@ -264,8 +265,13 @@ void QgsInvertedPolygonRenderer::stopRender( QgsRenderContext& context )
264
265
265
266
for ( int i = 0 ; i < multi.size (); i++ )
266
267
{
268
+ const QgsPolyline& exterior = multi[i][0 ];
267
269
// add the exterior ring as interior ring to the first polygon
268
- finalMulti[0 ].append ( multi[i][0 ] );
270
+ // make sure it satisfies at least very basic requirements of GEOS
271
+ // (otherwise the creation of GEOS geometry will fail)
272
+ if ( exterior.count () < 4 || exterior[0 ] != exterior[exterior.count () - 1 ] )
273
+ continue ;
274
+ finalMulti[0 ].append ( exterior );
269
275
270
276
// add interior rings as new polygons
271
277
for ( int j = 1 ; j < multi[i].size (); j++ )
@@ -275,14 +281,15 @@ void QgsInvertedPolygonRenderer::stopRender( QgsRenderContext& context )
275
281
finalMulti.append ( new_poly );
276
282
}
277
283
}
278
- feat.setGeometry ( QgsGeometry::fromMultiPolygon ( finalMulti ) );
279
284
}
285
+ feat.setGeometry ( QgsGeometry::fromMultiPolygon ( finalMulti ) );
280
286
}
281
- mSubRenderer ->renderFeature ( feat, mContext );
287
+ if ( feat.geometry () )
288
+ mSubRenderer ->renderFeature ( feat, mContext );
282
289
}
283
290
for ( FeatureCategoryVector::iterator cit = mFeaturesCategories .begin (); cit != mFeaturesCategories .end (); ++cit )
284
291
{
285
- foreach ( QgsGeometry* g, cit->geometries )
292
+ foreach ( QgsGeometry* g, cit->geometries )
286
293
{
287
294
delete g;
288
295
}
0 commit comments