Skip to content

Commit

Permalink
Add generic method to QgsMapLayerFactory to create map layers of
Browse files Browse the repository at this point in the history
any type
  • Loading branch information
nyalldawson committed Jun 23, 2021
1 parent 07f5812 commit 00db282
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 1 deletion.
10 changes: 10 additions & 0 deletions python/core/auto_generated/qgsmaplayerfactory.sip.in
Expand Up @@ -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

};
Expand Down
50 changes: 50 additions & 0 deletions src/core/qgsmaplayerfactory.cpp
Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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;
}
11 changes: 11 additions & 0 deletions src/core/qgsmaplayerfactory.h
Expand Up @@ -20,6 +20,7 @@

#include "qgis_core.h"
#include "qgis.h"
#include "qgscoordinatetransformcontext.h"

#include <QString>

Expand Down Expand Up @@ -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
56 changes: 55 additions & 1 deletion tests/src/python/test_qgsmaplayerfactory.py
Expand Up @@ -12,8 +12,21 @@

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()

Expand Down Expand Up @@ -62,6 +75,47 @@ def testTypeToString(self):
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()

0 comments on commit 00db282

Please sign in to comment.