Skip to content
Permalink
Browse files

[OGR provider] Make feature iterator work on GeometryCollection subla…

…yers

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
  • Loading branch information
rouault committed Oct 7, 2016
1 parent 6d5e735 commit 319bb9d050bd4ed59e04f89211838aafa2fbb912
@@ -313,8 +313,13 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
else
feature.setGeometry( nullptr );

if (( useIntersect && ( !feature.constGeometry() || !feature.constGeometry()->intersects( mRequest.filterRect() ) ) )
|| ( geometryTypeFilter && ( !feature.constGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.constGeometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
{
// OK
}
else if (( useIntersect && ( !feature.constGeometry() || !feature.constGeometry()->intersects( mRequest.filterRect() ) ) )
|| ( geometryTypeFilter && ( !feature.constGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.constGeometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
{
OGR_F_Destroy( fet );
return false;
@@ -361,7 +366,8 @@ QgsOgrFeatureSource::QgsOgrFeatureSource( const QgsOgrProvider* p )
mFieldsWithoutFid.append( mFields.at( i ) );
mDriverName = p->ogrDriverName;
mFirstFieldIsFid = p->mFirstFieldIsFid;
mOgrGeometryTypeFilter = wkbFlatten( p->mOgrGeometryTypeFilter );
mOgrGeometryTypeFilter = QgsOgrProvider::ogrWkbSingleFlatten( p->mOgrGeometryTypeFilter );
QgsDebugMsg( QString( "mOgrGeometryTypeFilter: %1" ).arg( mOgrGeometryTypeFilter ) );
QgsOgrConnPool::instance()->ref( mDataSource );
}

@@ -3157,13 +3157,16 @@ void QgsOgrProvider::recalculateFeatureCount()
setRelevantFields( ogrLayer, true, QgsAttributeList() );
OGR_L_ResetReading( ogrLayer );
OGRFeatureH fet;
const OGRwkbGeometryType flattenGeomTypeFilter =
QgsOgrProvider::ogrWkbSingleFlatten( mOgrGeometryTypeFilter );
while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) )
{
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
if ( geom )
{
OGRwkbGeometryType gType = OGR_G_GetGeometryType( geom );
if ( gType == mOgrGeometryTypeFilter ) mFeaturesCounted++;
gType = QgsOgrProvider::ogrWkbSingleFlatten( gType );
if ( gType == flattenGeomTypeFilter ) mFeaturesCounted++;
}
OGR_F_Destroy( fet );
}
@@ -221,5 +221,24 @@ def testNoDanglingFileDescriptorAfterCloseVariant2(self):
os.unlink(datasource)
self.assertFalse(os.path.exists(datasource))

def testGeometryCollection(self):
''' Test that we can at least retrieves attribute of features with geometry collection '''

datasource = os.path.join(self.basetestpath, 'testGeometryCollection.csv')
with open(datasource, 'wt') as f:
f.write('id,WKT\n')
f.write('1,POINT Z(2 49 0)\n')
f.write('2,GEOMETRYCOLLECTION Z (POINT Z (2 49 0))\n')

vl = QgsVectorLayer('{}|layerid=0|geometrytype=GeometryCollection'.format(datasource), 'test', 'ogr')
self.assertTrue(vl.isValid())
self.assertTrue(vl.featureCount(), 1)
values = [f['id'] for f in vl.getFeatures()]
self.assertEqual(values, ['2'])
del vl

os.unlink(datasource)
self.assertFalse(os.path.exists(datasource))

if __name__ == '__main__':
unittest.main()

0 comments on commit 319bb9d

Please sign in to comment.
You can’t perform that action at this time.