Merge pull request #55598 from nyalldawson/fix_remove_geom

Ensure layer renderer is removed when changing data source from a spatial to a non-spatial type
This commit is contained in:
Julien Cabieces 2023-12-14 16:52:27 +01:00 committed by GitHub
commit 7a1937536a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 4 deletions

View File

@ -2033,10 +2033,10 @@ void QgsVectorLayer::setDataSourcePrivate( const QString &dataSource, const QStr
}
// if the default style failed to load or was disabled use some very basic defaults
if ( !defaultLoadedFlag && isSpatial() )
if ( !defaultLoadedFlag )
{
// add single symbol renderer
setRenderer( QgsFeatureRenderer::defaultRenderer( geometryType() ) );
// add single symbol renderer for spatial layers
setRenderer( isSpatial() ? QgsFeatureRenderer::defaultRenderer( geometryType() ) : nullptr );
}
if ( !mSetLegendFromStyle )
@ -4179,7 +4179,10 @@ void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r )
// we must allow setting a renderer if our geometry type is unknown
// as this allows the renderer to be correctly set even for layers
// with broken sources
if ( !isSpatial() && mWkbType != Qgis::WkbType::Unknown )
// (note that we allow REMOVING the renderer for non-spatial layers,
// e.g. to permit removing the renderer when the layer changes from
// a spatial layer to a non-spatial one)
if ( r && !isSpatial() && mWkbType != Qgis::WkbType::Unknown )
return;
if ( r != mRenderer )

View File

@ -374,6 +374,19 @@ class TestQgsVectorLayer(QgisTestCase, FeatureSourceTestCase):
self.assertNotEqual(layer.renderer(), r)
self.assertEqual(layer.renderer().symbol().type(), QgsSymbol.Fill)
# reset layer to a non-spatial layer
lines_path = os.path.join(unitTestDataPath(), 'nonspatial.dbf')
layer.setDataSource(lines_path, 'new name2', 'ogr', options)
self.assertTrue(layer.isValid())
self.assertEqual(layer.name(), 'new name2')
self.assertEqual(layer.wkbType(), QgsWkbTypes.NoGeometry)
self.assertFalse(layer.crs().isValid())
self.assertIn('nonspatial.dbf', layer.dataProvider().dataSourceUri())
self.assertEqual(len(spy), 3)
# should have REMOVED renderer
self.assertIsNone(layer.renderer())
def testSetDataSourceInvalidToValid(self):
"""
Test that changing an invalid layer path to valid maintains the renderer