diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 7b0cee02c4d9..e8640e21b389 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -221,11 +221,20 @@ QgsVectorLayer::~QgsVectorLayer() QgsVectorLayer *QgsVectorLayer::clone() const { QgsVectorLayer::LayerOptions options; + // We get the data source string from the provider when + // possible because some providers may have changed it + // directly (memory provider does that). + QString dataSource; if ( mDataProvider ) { + dataSource = mDataProvider->dataSourceUri(); options.transformContext = mDataProvider->transformContext(); } - QgsVectorLayer *layer = new QgsVectorLayer( source(), name(), mProviderKey, options ); + else + { + dataSource = source(); + } + QgsVectorLayer *layer = new QgsVectorLayer( dataSource, name(), mProviderKey, options ); if ( mDataProvider && layer->dataProvider() ) { layer->dataProvider()->handlePostCloneOperations( mDataProvider ); diff --git a/tests/src/python/test_provider_memory.py b/tests/src/python/test_provider_memory.py index 7dbee12cf852..210c6180fd6f 100644 --- a/tests/src/python/test_provider_memory.py +++ b/tests/src/python/test_provider_memory.py @@ -10,6 +10,7 @@ __date__ = '2015-04-23' __copyright__ = 'Copyright 2015, The QGIS Project' +from urllib.parse import parse_qs from qgis.core import ( QgsField, @@ -652,6 +653,24 @@ def testSpatialIndex(self): vl.dataProvider().createSpatialIndex() self.assertEqual(vl.hasSpatialIndex(), QgsFeatureSource.SpatialIndexPresent) + def testClone(self): + """Test that a cloned layer has a single new id and + the same fields as the source layer""" + + vl = QgsVectorLayer( + 'Point?crs=epsg:4326', + 'test', 'memory') + self.assertTrue(vl.isValid) + dp = vl.dataProvider() + self.assertTrue(dp.addAttributes([QgsField("name", QVariant.String), + QgsField("age", QVariant.Int), + QgsField("size", QVariant.Double)])) + vl2 = vl.clone() + self.assertTrue('memory?geometry=Point&crs=EPSG:4326&field=name:(0,0)&field=age:(0,0)&field=size:(0,0)' in vl2.publicSource()) + self.assertEqual(len(parse_qs(vl.publicSource())['uid']), 1) + self.assertEqual(len(parse_qs(vl2.publicSource())['uid']), 1) + self.assertNotEqual(parse_qs(vl2.publicSource())['uid'][0], parse_qs(vl.publicSource())['uid'][0]) + class TestPyQgsMemoryProviderIndexed(unittest.TestCase, ProviderTestCase):