Skip to content

Commit

Permalink
[OGR provider] Make feature iterator work on GeometryCollection subla…
Browse files Browse the repository at this point in the history
…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 3a906a1 commit a5a18c2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
12 changes: 9 additions & 3 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,13 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
else
feature.clearGeometry();

if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
|| ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
{
// OK
}
else if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
|| ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
{
OGR_F_Destroy( fet );
return false;
Expand Down Expand Up @@ -359,7 +364,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 );
}

Expand Down
5 changes: 4 additions & 1 deletion src/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3155,13 +3155,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 );
}
Expand Down
19 changes: 19 additions & 0 deletions tests/src/python/test_provider_ogr.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 a5a18c2

Please sign in to comment.