Skip to content

Commit 319bb9d

Browse files
committed
[OGR provider] Make feature iterator work on GeometryCollection sublayers
When trying to reproduce http://hub.qgis.org/issues/10485, I noticed a regression. Now attribute table no longer shows features with OGR GeometryCollection. Fixes also issues where sublayer geometry type is too strict regarding 2D vs 2.5D geometry types. Fixes #15675
1 parent 6d5e735 commit 319bb9d

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

src/providers/ogr/qgsogrfeatureiterator.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,13 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
313313
else
314314
feature.setGeometry( nullptr );
315315

316-
if (( useIntersect && ( !feature.constGeometry() || !feature.constGeometry()->intersects( mRequest.filterRect() ) ) )
317-
|| ( geometryTypeFilter && ( !feature.constGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.constGeometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
316+
if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
317+
geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
318+
{
319+
// OK
320+
}
321+
else if (( useIntersect && ( !feature.constGeometry() || !feature.constGeometry()->intersects( mRequest.filterRect() ) ) )
322+
|| ( geometryTypeFilter && ( !feature.constGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.constGeometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
318323
{
319324
OGR_F_Destroy( fet );
320325
return false;
@@ -361,7 +366,8 @@ QgsOgrFeatureSource::QgsOgrFeatureSource( const QgsOgrProvider* p )
361366
mFieldsWithoutFid.append( mFields.at( i ) );
362367
mDriverName = p->ogrDriverName;
363368
mFirstFieldIsFid = p->mFirstFieldIsFid;
364-
mOgrGeometryTypeFilter = wkbFlatten( p->mOgrGeometryTypeFilter );
369+
mOgrGeometryTypeFilter = QgsOgrProvider::ogrWkbSingleFlatten( p->mOgrGeometryTypeFilter );
370+
QgsDebugMsg( QString( "mOgrGeometryTypeFilter: %1" ).arg( mOgrGeometryTypeFilter ) );
365371
QgsOgrConnPool::instance()->ref( mDataSource );
366372
}
367373

src/providers/ogr/qgsogrprovider.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3157,13 +3157,16 @@ void QgsOgrProvider::recalculateFeatureCount()
31573157
setRelevantFields( ogrLayer, true, QgsAttributeList() );
31583158
OGR_L_ResetReading( ogrLayer );
31593159
OGRFeatureH fet;
3160+
const OGRwkbGeometryType flattenGeomTypeFilter =
3161+
QgsOgrProvider::ogrWkbSingleFlatten( mOgrGeometryTypeFilter );
31603162
while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) )
31613163
{
31623164
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
31633165
if ( geom )
31643166
{
31653167
OGRwkbGeometryType gType = OGR_G_GetGeometryType( geom );
3166-
if ( gType == mOgrGeometryTypeFilter ) mFeaturesCounted++;
3168+
gType = QgsOgrProvider::ogrWkbSingleFlatten( gType );
3169+
if ( gType == flattenGeomTypeFilter ) mFeaturesCounted++;
31673170
}
31683171
OGR_F_Destroy( fet );
31693172
}

tests/src/python/test_provider_ogr.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,24 @@ def testNoDanglingFileDescriptorAfterCloseVariant2(self):
221221
os.unlink(datasource)
222222
self.assertFalse(os.path.exists(datasource))
223223

224+
def testGeometryCollection(self):
225+
''' Test that we can at least retrieves attribute of features with geometry collection '''
226+
227+
datasource = os.path.join(self.basetestpath, 'testGeometryCollection.csv')
228+
with open(datasource, 'wt') as f:
229+
f.write('id,WKT\n')
230+
f.write('1,POINT Z(2 49 0)\n')
231+
f.write('2,GEOMETRYCOLLECTION Z (POINT Z (2 49 0))\n')
232+
233+
vl = QgsVectorLayer('{}|layerid=0|geometrytype=GeometryCollection'.format(datasource), 'test', 'ogr')
234+
self.assertTrue(vl.isValid())
235+
self.assertTrue(vl.featureCount(), 1)
236+
values = [f['id'] for f in vl.getFeatures()]
237+
self.assertEqual(values, ['2'])
238+
del vl
239+
240+
os.unlink(datasource)
241+
self.assertFalse(os.path.exists(datasource))
242+
224243
if __name__ == '__main__':
225244
unittest.main()

0 commit comments

Comments
 (0)