Skip to content

Commit

Permalink
Merge pull request #7132 from rouault/fix_19077_bis
Browse files Browse the repository at this point in the history
 [OGR provider] Avoid attribute table to be empty on OGR layer with mixed geom types (fixes #19077)
  • Loading branch information
rouault authored May 31, 2018
2 parents 0cffd19 + 2969ba1 commit efa7f99
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/providers/ogr/qgsogrfeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource *source, bool
return;
}

mFetchGeometry = ( !mFilterRect.isNull() ) || !( mRequest.flags() & QgsFeatureRequest::NoGeometry );
mFetchGeometry = ( !mFilterRect.isNull() ) ||
!( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ||
( mSource->mOgrGeometryTypeFilter != wkbUnknown );

QgsAttributeList attrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();

// ensure that all attributes required for expression filter are being fetched
Expand Down
1 change: 1 addition & 0 deletions src/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ static OGRwkbGeometryType ogrWkbGeometryTypeFromName( const QString &typeName )
else if ( typeName == QLatin1String( "MultiLineString25D" ) ) return wkbMultiLineString25D;
else if ( typeName == QLatin1String( "MultiPolygon25D" ) ) return wkbMultiPolygon25D;
else if ( typeName == QLatin1String( "GeometryCollection25D" ) ) return wkbGeometryCollection25D;
QgsDebugMsg( QStringLiteral( "unknown geometry type: %1" ).arg( typeName ) );
return wkbUnknown;
}

Expand Down
36 changes: 34 additions & 2 deletions tests/src/python/test_provider_ogr_gpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,8 +841,11 @@ def testCreateSpatialIndex(self):
def testSubSetStringEditable_bug17795(self):
"""Test that a layer is not editable after setting a subset and it's reverted to editable after the filter is removed"""

tmpfile = os.path.join(self.basetestpath, 'testSubSetStringEditable_bug17795.gpkg')
shutil.copy(TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg', tmpfile)

isEditable = QgsVectorDataProvider.ChangeAttributeValues
testPath = TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg|layername=bug_17795'
testPath = tmpfile + '|layername=bug_17795'

vl = QgsVectorLayer(testPath, 'subset_test', 'ogr')
self.assertTrue(vl.isValid())
Expand All @@ -868,7 +871,10 @@ def testSubsetStringExtent_bug17863(self):
def _lessdigits(s):
return re.sub(r'(\d+\.\d{3})\d+', r'\1', s)

testPath = TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg|layername=bug_17795'
tmpfile = os.path.join(self.basetestpath, 'testSubsetStringExtent_bug17863.gpkg')
shutil.copy(TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg', tmpfile)

testPath = tmpfile + '|layername=bug_17795'
subSetString = '"name" = \'int\''
subSet = '|layername=bug_17795|subset=%s' % subSetString

Expand Down Expand Up @@ -897,6 +903,32 @@ def _lessdigits(s):
self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent)
self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)

def testRequestWithoutGeometryOnLayerMixedGeometry(self):
""" Test bugfix for https://issues.qgis.org/issues/19077 """

# Issue is more a generic one of the OGR provider, but easy to trigger with GPKG

tmpfile = os.path.join(self.basetestpath, 'testRequestWithoutGeometryOnLayerMixedGeometry.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbUnknown, options=['SPATIAL_INDEX=NO'])
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)'))
lyr.CreateFeature(f)
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('LINESTRING(0 0,1 0)'))
lyr.CreateFeature(f)
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('LINESTRING(0 0,1 0)'))
lyr.CreateFeature(f)
f = None
ds = None

vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|geometrytype=Point|layername=" + "test", 'test', u'ogr')
self.assertTrue(vl.isValid())
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
features = [f for f in vl.getFeatures(request)]
self.assertEqual(len(features), 1)


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

0 comments on commit efa7f99

Please sign in to comment.