Skip to content

Commit a5a18c2

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 3a906a1 commit a5a18c2

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

src/providers/ogr/qgsogrfeatureiterator.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,13 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
311311
else
312312
feature.clearGeometry();
313313

314-
if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
315-
|| ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
314+
if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
315+
geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
316+
{
317+
// OK
318+
}
319+
else if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
320+
|| ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
316321
{
317322
OGR_F_Destroy( fet );
318323
return false;
@@ -359,7 +364,8 @@ QgsOgrFeatureSource::QgsOgrFeatureSource( const QgsOgrProvider* p )
359364
mFieldsWithoutFid.append( mFields.at( i ) );
360365
mDriverName = p->ogrDriverName;
361366
mFirstFieldIsFid = p->mFirstFieldIsFid;
362-
mOgrGeometryTypeFilter = wkbFlatten( p->mOgrGeometryTypeFilter );
367+
mOgrGeometryTypeFilter = QgsOgrProvider::ogrWkbSingleFlatten( p->mOgrGeometryTypeFilter );
368+
QgsDebugMsg( QString( "mOgrGeometryTypeFilter: %1" ).arg( mOgrGeometryTypeFilter ) );
363369
QgsOgrConnPool::instance()->ref( mDataSource );
364370
}
365371

src/providers/ogr/qgsogrprovider.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -3155,13 +3155,16 @@ void QgsOgrProvider::recalculateFeatureCount()
31553155
setRelevantFields( ogrLayer, true, QgsAttributeList() );
31563156
OGR_L_ResetReading( ogrLayer );
31573157
OGRFeatureH fet;
3158+
const OGRwkbGeometryType flattenGeomTypeFilter =
3159+
QgsOgrProvider::ogrWkbSingleFlatten( mOgrGeometryTypeFilter );
31583160
while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) )
31593161
{
31603162
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
31613163
if ( geom )
31623164
{
31633165
OGRwkbGeometryType gType = OGR_G_GetGeometryType( geom );
3164-
if ( gType == mOgrGeometryTypeFilter ) mFeaturesCounted++;
3166+
gType = QgsOgrProvider::ogrWkbSingleFlatten( gType );
3167+
if ( gType == flattenGeomTypeFilter ) mFeaturesCounted++;
31653168
}
31663169
OGR_F_Destroy( fet );
31673170
}

tests/src/python/test_provider_ogr.py

+19
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)