Skip to content
Browse files
Don't reset metadata when changing a layer's source
Fixes #42821
Fixes #39226
  • Loading branch information
nyalldawson committed May 4, 2021
1 parent b4f1090 commit bdf8b799d459d44f866a51c6bec48477f8162c1c
Showing with 42 additions and 2 deletions.
  1. +7 −1 src/core/vector/qgsvectorlayer.cpp
  2. +35 −1 tests/src/python/
@@ -1783,7 +1783,13 @@ bool QgsVectorLayer::setDataProvider( QString const &provider, const QgsDataProv
profile->switchTask( tr( "Read layer metadata" ) );
if ( mDataProvider->capabilities() & QgsVectorDataProvider::ReadLayerMetadata )
setMetadata( mDataProvider->layerMetadata() );
// we combine the provider metadata with the layer's existing metadata, so as not to reset any user customisations to the metadata
// back to the default if a layer's data source is changed
QgsLayerMetadata newMetadata = mDataProvider->layerMetadata();
// this overwrites the provider metadata with any properties which are non-empty from the existing layer metadata
newMetadata.combine( &mMetadata );

setMetadata( newMetadata );
QgsDebugMsgLevel( QStringLiteral( "Set Data provider QgsLayerMetadata identifier[%1]" ).arg( metadata().identifier() ), 4 );

@@ -20,7 +20,8 @@
from qgis.core import (QgsReadWriteContext,
from qgis.testing import start_app, unittest
from qgis.PyQt.QtXml import QDomDocument
from qgis.PyQt.QtCore import QTemporaryDir
@@ -200,6 +201,39 @@ def testQgsMapLayerProject(self):

def testRetainLayerMetadataWhenChangingDataSource(self):
Test that we retain existing layer metadata when a layer's source is changed
vl = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'points.shp'), "layer", "ogr")

metadata = QgsLayerMetadata()
metadata.setRights(['original right 1', 'original right 2'])
metadata.setAbstract('original abstract')

# now change layer datasource to one which has embedded provider medata
datasource = os.path.join(unitTestDataPath(), 'gdb_metadata.gdb')
vl.setDataSource(datasource, 'test', 'ogr')

# these settings weren't present in the original layer metadata, so should have been taken from the GDB file
self.assertEqual(vl.metadata().identifier(), 'Test')
self.assertEqual(vl.metadata().title(), 'Title')
self.assertEqual(vl.metadata().type(), 'dataset')
self.assertEqual(vl.metadata().language(), 'ENG')
self.assertEqual(vl.metadata().keywords(), {'Search keys': ['Tags']})
self.assertEqual(vl.metadata().constraints()[0].type, 'Limitations of use')
self.assertEqual(vl.metadata().constraints()[0].constraint, 'This is the use limitation')
self.assertEqual(vl.metadata().extent().spatialExtents()[0].bounds.xMinimum(), 1)
self.assertEqual(vl.metadata().extent().spatialExtents()[0].bounds.xMaximum(), 2)
self.assertEqual(vl.metadata().extent().spatialExtents()[0].bounds.yMinimum(), 3)
self.assertEqual(vl.metadata().extent().spatialExtents()[0].bounds.yMaximum(), 4)

# these setting WERE present, so must be retained
self.assertIn('original abstract', vl.metadata().abstract())
self.assertEqual(vl.metadata().rights(), ['original right 1', 'original right 2'])

if __name__ == '__main__':

0 comments on commit bdf8b79

Please sign in to comment.