Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add QgsProjectUtils utility class with function for retrieving layers…
… matching a file path from a project
  • Loading branch information
nyalldawson committed Jul 28, 2021
1 parent 216925a commit 8ce3473
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 0 deletions.
43 changes: 43 additions & 0 deletions python/core/auto_generated/project/qgsprojectutils.sip.in
@@ -0,0 +1,43 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/project/qgsprojectutils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsProjectUtils
{
%Docstring(signature="appended")
Contains utility functions for working with QGIS projects.

.. versionadded:: 3.22
%End

%TypeHeaderCode
#include "qgsprojectutils.h"
%End
public:

static QList< QgsMapLayer * > layersMatchingPath( const QgsProject *project, const QString &path );
%Docstring
Returns a list of all layers in the specified ``project`` which match the given ``path``.

This method can be used to retrieve a list of layers in a project associated with a file path.
%End

};



/************************************************************************
* This file has been generated automatically from *
* *
* src/core/project/qgsprojectutils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -509,6 +509,7 @@
%Include auto_generated/project/qgsprojectstorageregistry.sip
%Include auto_generated/project/qgsprojecttimesettings.sip
%Include auto_generated/project/qgsprojecttranslator.sip
%Include auto_generated/project/qgsprojectutils.sip
%Include auto_generated/project/qgsprojectversion.sip
%Include auto_generated/project/qgsprojectviewsettings.sip
%Include auto_generated/providers/qgsabstractdatabaseproviderconnection.sip
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -608,6 +608,7 @@ set(QGIS_CORE_SRCS
project/qgsprojectstorage.cpp
project/qgsprojectstorageregistry.cpp
project/qgsprojecttimesettings.cpp
project/qgsprojectutils.cpp
project/qgsprojectversion.cpp
project/qgsprojectviewsettings.cpp

Expand Down Expand Up @@ -1521,6 +1522,7 @@ set(QGIS_CORE_HDRS
project/qgsprojectstorageregistry.h
project/qgsprojecttimesettings.h
project/qgsprojecttranslator.h
project/qgsprojectutils.h
project/qgsprojectversion.h
project/qgsprojectviewsettings.h

Expand Down
37 changes: 37 additions & 0 deletions src/core/project/qgsprojectutils.cpp
@@ -0,0 +1,37 @@
/***************************************************************************
qgsprojectutils.h
-------------------
begin : July 2021
copyright : (C) 2021 Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsprojectutils.h"
#include "qgsmaplayerutils.h"
#include "qgsproject.h"

QList<QgsMapLayer *> QgsProjectUtils::layersMatchingPath( const QgsProject *project, const QString &path )
{
QList<QgsMapLayer *> layersList;
if ( !project )
return layersList;

const QMap<QString, QgsMapLayer *> mapLayers( project->mapLayers() );
for ( QgsMapLayer *layer : mapLayers )
{
if ( QgsMapLayerUtils::layerSourceMatchesPath( layer, path ) )
{
layersList << layer;
}
}
return layersList;
}
50 changes: 50 additions & 0 deletions src/core/project/qgsprojectutils.h
@@ -0,0 +1,50 @@
/***************************************************************************
qgsprojectutils.h
-------------------
begin : July 2021
copyright : (C) 2021 Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPROJECTUTILS_H
#define QGSPROJECTUTILS_H

#include "qgis_sip.h"
#include "qgis_core.h"
#include "qgis.h"

#include <QList>

class QgsProject;
class QgsMapLayer;

/**
* \ingroup core
* \brief Contains utility functions for working with QGIS projects.
* \since QGIS 3.22
*/
class CORE_EXPORT QgsProjectUtils
{

public:

/**
* Returns a list of all layers in the specified \a project which match the given \a path.
*
* This method can be used to retrieve a list of layers in a project associated with a file path.
*/
static QList< QgsMapLayer * > layersMatchingPath( const QgsProject *project, const QString &path );

};

#endif // QGSPROJECTUTILS_H


1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -238,6 +238,7 @@ ADD_PYTHON_TEST(PyQgsProcessingParameters test_qgsprocessingparameters.py)
ADD_PYTHON_TEST(PyQgsProjectionSelectionWidgets test_qgsprojectionselectionwidgets.py)
ADD_PYTHON_TEST(PyQgsProjectMetadata test_qgsprojectmetadata.py)
ADD_PYTHON_TEST(PyQgsProjectServerValidator test_qgsprojectservervalidator.py)
ADD_PYTHON_TEST(PyQgsProjectUtils test_qgsprojectutils.py)
ADD_PYTHON_TEST(PyQgsPropertyOverrideButton test_qgspropertyoverridebutton.py)
ADD_PYTHON_TEST(PyQgsProviderConnectionComboBox test_qgsproviderconnectioncombobox.py)
ADD_PYTHON_TEST(PyQgsProviderConnectionModel test_qgsproviderconnectionmodel.py)
Expand Down
67 changes: 67 additions & 0 deletions tests/src/python/test_qgsprojectutils.py
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsProjectUtils.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '2021-07'
__copyright__ = 'Copyright 2021, The QGIS Project'


import qgis # NOQA

from qgis.testing import unittest
from qgis.core import (
QgsProjectUtils,
QgsCoordinateReferenceSystem,
QgsCoordinateTransformContext,
QgsVectorLayer,
QgsRasterLayer,
QgsProject
)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath

start_app()


class TestQgsProjectUtils(unittest.TestCase):

def test_layersMatchingPath(self):
"""
Test QgsProjectUtils.layersMatchingPath()
"""
self.assertFalse(QgsProjectUtils.layersMatchingPath(None, ''))
self.assertFalse(QgsProjectUtils.layersMatchingPath(None, 'aaaaa'))

# add some layers to a project
# shapefile
layer1 = QgsVectorLayer(unitTestDataPath() + '/points.shp', 'l1')
self.assertTrue(layer1.isValid())
p = QgsProject()
p.addMapLayer(layer1)

gpkg1 = QgsVectorLayer(unitTestDataPath() + '/mixed_layers.gpkg|layername=lines', 'l1')
self.assertTrue(gpkg1.isValid())
p.addMapLayer(gpkg1)

gpkg2 = QgsVectorLayer(unitTestDataPath() + '/mixed_layers.gpkg|layername=points', 'l1')
self.assertTrue(gpkg2.isValid())
p.addMapLayer(gpkg2)

# raster layer from gpkg
rl = QgsRasterLayer(f'GPKG:{unitTestDataPath()}/mixed_layers.gpkg:band1')
self.assertTrue(rl.isValid())
p.addMapLayer(rl)

self.assertFalse(QgsProjectUtils.layersMatchingPath(p, ''))
self.assertFalse(QgsProjectUtils.layersMatchingPath(p, 'aaa'))
self.assertCountEqual(QgsProjectUtils.layersMatchingPath(p, unitTestDataPath() + '/points.shp'), [layer1])
self.assertCountEqual(QgsProjectUtils.layersMatchingPath(p, unitTestDataPath() + '/mixed_layers.gpkg'), [gpkg1, gpkg2, rl])


if __name__ == '__main__':
unittest.main()

0 comments on commit 8ce3473

Please sign in to comment.