diff --git a/python/core/auto_generated/qgsmaplayerfactory.sip.in b/python/core/auto_generated/qgsmaplayerfactory.sip.in index 2d26eb860c2..440b8483d7b 100644 --- a/python/core/auto_generated/qgsmaplayerfactory.sip.in +++ b/python/core/auto_generated/qgsmaplayerfactory.sip.in @@ -41,6 +41,16 @@ Returns the map layer type corresponding a ``string`` value. Converts a map layer ``type`` to a string value. .. seealso:: :py:func:`typeFromString` +%End + + static QgsMapLayer *createLayer( const QString &uri, const QString &name, QgsMapLayerType type, + const QString &provider = QString(), const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext() ) /Factory/; +%Docstring +Creates a map layer, given a ``uri``, ``name``, layer ``type`` and ``provider`` name. + +Caller takes ownership of the returned layer. + +.. versionadded:: 3.22 %End }; diff --git a/src/core/qgsmaplayerfactory.cpp b/src/core/qgsmaplayerfactory.cpp index 2132158dd80..7e810daf55a 100644 --- a/src/core/qgsmaplayerfactory.cpp +++ b/src/core/qgsmaplayerfactory.cpp @@ -16,6 +16,12 @@ ***************************************************************************/ #include "qgsmaplayerfactory.h" +#include "qgsvectorlayer.h" +#include "qgsrasterlayer.h" +#include "qgsmeshlayer.h" +#include "qgspointcloudlayer.h" +#include "qgsvectortilelayer.h" +#include "qgsannotationlayer.h" QgsMapLayerType QgsMapLayerFactory::typeFromString( const QString &string, bool &ok ) { @@ -60,3 +66,47 @@ QString QgsMapLayerFactory::typeToString( QgsMapLayerType type ) } return QString(); } + +QgsMapLayer *QgsMapLayerFactory::createLayer( const QString &uri, const QString &name, QgsMapLayerType type, const QString &provider, const QgsCoordinateTransformContext &transformContext ) +{ + switch ( type ) + { + case QgsMapLayerType::VectorLayer: + { + QgsVectorLayer::LayerOptions options; + options.transformContext = transformContext; + return new QgsVectorLayer( uri, name, provider, options ); + } + + case QgsMapLayerType::RasterLayer: + { + QgsRasterLayer::LayerOptions options; + options.transformContext = transformContext; + return new QgsRasterLayer( uri, name, provider, options ); + } + + case QgsMapLayerType::MeshLayer: + { + QgsMeshLayer::LayerOptions options; + options.transformContext = transformContext; + return new QgsMeshLayer( uri, name, provider, options ); + } + + case QgsMapLayerType::VectorTileLayer: + return new QgsVectorTileLayer( uri, name ); + + case QgsMapLayerType::AnnotationLayer: + return new QgsAnnotationLayer( name, QgsAnnotationLayer::LayerOptions( transformContext ) ); + + case QgsMapLayerType::PointCloudLayer: + { + QgsPointCloudLayer::LayerOptions options; + options.transformContext = transformContext; + return new QgsPointCloudLayer( uri, name, provider, options ); + } + + case QgsMapLayerType::PluginLayer: + break; + } + return nullptr; +} diff --git a/src/core/qgsmaplayerfactory.h b/src/core/qgsmaplayerfactory.h index 3c1ffdce690..f7186d5c1fc 100644 --- a/src/core/qgsmaplayerfactory.h +++ b/src/core/qgsmaplayerfactory.h @@ -20,6 +20,7 @@ #include "qgis_core.h" #include "qgis.h" +#include "qgscoordinatetransformcontext.h" #include @@ -52,6 +53,16 @@ class CORE_EXPORT QgsMapLayerFactory */ static QString typeToString( QgsMapLayerType type ); + /** + * Creates a map layer, given a \a uri, \a name, layer \a type and \a provider name. + * + * Caller takes ownership of the returned layer. + * + * \since QGIS 3.22 + */ + static QgsMapLayer *createLayer( const QString &uri, const QString &name, QgsMapLayerType type, + const QString &provider = QString(), const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext() ) SIP_FACTORY; + }; #endif // QGSMAPLAYERFACTORY_H diff --git a/tests/src/python/test_qgsmaplayerfactory.py b/tests/src/python/test_qgsmaplayerfactory.py index 8c651aae146..2949bc0bd13 100644 --- a/tests/src/python/test_qgsmaplayerfactory.py +++ b/tests/src/python/test_qgsmaplayerfactory.py @@ -12,8 +12,21 @@ __copyright__ = 'Copyright 2021, The QGIS Project' import qgis # NOQA -from qgis.core import QgsMapLayerFactory, QgsMapLayerType +import os + +from qgis.core import ( + QgsMapLayerFactory, + QgsMapLayerType, + QgsVectorLayer, + QgsRasterLayer, + QgsMeshLayer, + QgsPointCloudLayer, + QgsAnnotationLayer, + QgsVectorTileLayer, + QgsDataSourceUri +) from qgis.testing import start_app, unittest +from utilities import unitTestDataPath start_app() @@ -62,6 +75,47 @@ class TestQgsMapLayerFactory(unittest.TestCase): QgsMapLayerFactory.typeFromString(QgsMapLayerFactory.typeToString(QgsMapLayerType.AnnotationLayer))[0], QgsMapLayerType.AnnotationLayer) + def testCreateLayer(self): + # create vector + ml = QgsMapLayerFactory.createLayer(os.path.join(unitTestDataPath(), 'lines.shp'), 'lines', QgsMapLayerType.VectorLayer, 'ogr') + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsVectorLayer) + self.assertEqual(ml.name(), 'lines') + + # create raster + ml = QgsMapLayerFactory.createLayer(os.path.join(unitTestDataPath(), 'landsat.tif'), 'rl', QgsMapLayerType.RasterLayer, 'gdal') + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsRasterLayer) + self.assertEqual(ml.name(), 'rl') + + # create mesh + ml = QgsMapLayerFactory.createLayer(os.path.join(unitTestDataPath(), 'mesh', 'lines.2dm'), 'ml', QgsMapLayerType.MeshLayer, 'mdal') + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsMeshLayer) + self.assertEqual(ml.name(), 'ml') + + # create point cloud + ml = QgsMapLayerFactory.createLayer(os.path.join(unitTestDataPath(), 'point_clouds', 'ept', 'rgb', 'ept.json'), 'pcl', QgsMapLayerType.PointCloudLayer, 'ept') + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsPointCloudLayer) + self.assertEqual(ml.name(), 'pcl') + + # annotation layer + ml = QgsMapLayerFactory.createLayer('', 'al', QgsMapLayerType.AnnotationLayer) + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsAnnotationLayer) + self.assertEqual(ml.name(), 'al') + + # vector tile layer + ds = QgsDataSourceUri() + ds.setParam("type", "xyz") + ds.setParam("url", "file://{}/{{z}}-{{x}}-{{y}}.pbf".format(os.path.join(unitTestDataPath(), 'vector_tile'))) + ds.setParam("zmax", "1") + ml = QgsMapLayerFactory.createLayer(ds.encodedUri().data().decode(), 'vtl', QgsMapLayerType.VectorTileLayer) + self.assertTrue(ml.isValid()) + self.assertIsInstance(ml, QgsVectorTileLayer) + self.assertEqual(ml.name(), 'vtl') + if __name__ == '__main__': unittest.main()