diff --git a/src/providers/pdal/qgspdalprovider.cpp b/src/providers/pdal/qgspdalprovider.cpp index 8103a1f389c..0c13f6c46fe 100644 --- a/src/providers/pdal/qgspdalprovider.cpp +++ b/src/providers/pdal/qgspdalprovider.cpp @@ -26,6 +26,8 @@ #include "qgspdaleptgenerationtask.h" #include "qgseptpointcloudindex.h" #include "qgstaskmanager.h" +#include "qgsprovidersublayerdetails.h" +#include "qgsproviderutils.h" #include #include @@ -284,7 +286,8 @@ QgsPdalProvider *QgsPdalProviderMetadata::createProvider( const QString &uri, co QgsProviderMetadata::ProviderMetadataCapabilities QgsPdalProviderMetadata::capabilities() const { return ProviderMetadataCapability::LayerTypesForUri - | ProviderMetadataCapability::PriorityForUri; + | ProviderMetadataCapability::PriorityForUri + | ProviderMetadataCapability::QuerySublayers; } QList QgsPdalProviderMetadata::dataItemProviders() const @@ -322,6 +325,25 @@ QList QgsPdalProviderMetadata::validLayerTypesForUri( const QSt return QList(); } +QList QgsPdalProviderMetadata::querySublayers( const QString &uri, Qgis::SublayerQueryFlags, QgsFeedback * ) const +{ + const QVariantMap parts = decodeUri( uri ); + const QFileInfo fi( parts.value( QStringLiteral( "path" ) ).toString() ); + if ( fi.suffix().compare( QLatin1String( "las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String( "laz" ), Qt::CaseInsensitive ) == 0 ) + { + QgsProviderSublayerDetails details; + details.setUri( uri ); + details.setProviderKey( QStringLiteral( "pdal" ) ); + details.setType( QgsMapLayerType::PointCloudLayer ); + details.setName( QgsProviderUtils::suggestLayerNameFromFilePath( uri ) ); + return {details}; + } + else + { + return {}; + } +} + QString QgsPdalProviderMetadata::filters( QgsProviderMetadata::FilterType type ) { switch ( type ) diff --git a/src/providers/pdal/qgspdalprovider.h b/src/providers/pdal/qgspdalprovider.h index 7958b31b31a..75e632ad2b4 100644 --- a/src/providers/pdal/qgspdalprovider.h +++ b/src/providers/pdal/qgspdalprovider.h @@ -80,6 +80,7 @@ class QgsPdalProviderMetadata : public QgsProviderMetadata QVariantMap decodeUri( const QString &uri ) const override; int priorityForUri( const QString &uri ) const override; QList< QgsMapLayerType > validLayerTypesForUri( const QString &uri ) const override; + QList< QgsProviderSublayerDetails > querySublayers( const QString &uri, Qgis::SublayerQueryFlags flags = Qgis::SublayerQueryFlags(), QgsFeedback *feedback = nullptr ) const override; QString filters( FilterType type ) override; ProviderCapabilities providerCapabilities() const override; }; diff --git a/tests/src/providers/testqgspdalprovider.cpp b/tests/src/providers/testqgspdalprovider.cpp index 844c6502004..2bdaf0c22d4 100644 --- a/tests/src/providers/testqgspdalprovider.cpp +++ b/tests/src/providers/testqgspdalprovider.cpp @@ -32,6 +32,7 @@ #include "qgsmaplayer.h" #include "qgspointcloudlayer.h" #include "qgspdaleptgenerationtask.h" +#include "qgsprovidersublayerdetails.h" /** * \ingroup UnitTests @@ -52,6 +53,7 @@ class TestQgsPdalProvider : public QObject void decodeUri(); void layerTypesForUri(); void preferredUri(); + void querySublayers(); void brokenPath(); void validLayer(); void testEptGeneration(); @@ -131,7 +133,7 @@ void TestQgsPdalProvider::preferredUri() QgsProviderMetadata *pdalMetadata = QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "pdal" ) ); QVERIFY( pdalMetadata->capabilities() & QgsProviderMetadata::PriorityForUri ); - // test that EPT is the preferred provider for las/laz uris + // test that pdal is the preferred provider for las/laz uris QList candidates = QgsProviderRegistry::instance()->preferredProvidersForUri( QStringLiteral( "/home/test/cloud.las" ) ); QCOMPARE( candidates.size(), 1 ); QCOMPARE( candidates.at( 0 ).metadata()->key(), QStringLiteral( "pdal" ) ); @@ -156,6 +158,33 @@ void TestQgsPdalProvider::preferredUri() QVERIFY( QgsProviderRegistry::instance()->shouldDeferUriForOtherProviders( QStringLiteral( "/home/test/cloud.las" ), QStringLiteral( "ept" ) ) ); } +void TestQgsPdalProvider::querySublayers() +{ + // test querying sub layers for a pdal layer + QgsProviderMetadata *pdalMetadata = QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "pdal" ) ); + + // invalid uri + QList< QgsProviderSublayerDetails >res = pdalMetadata->querySublayers( QString() ); + QVERIFY( res.empty() ); + + // not a pdal layer + res = pdalMetadata->querySublayers( QString( TEST_DATA_DIR ) + "/lines.shp" ); + QVERIFY( res.empty() ); + + // valid pdal layer + res = pdalMetadata->querySublayers( mTestDataDir + "/point_clouds/las/cloud.las" ); + QCOMPARE( res.count(), 1 ); + QCOMPARE( res.at( 0 ).name(), QStringLiteral( "cloud" ) ); + QCOMPARE( res.at( 0 ).uri(), mTestDataDir + "/point_clouds/las/cloud.las" ); + QCOMPARE( res.at( 0 ).providerKey(), QStringLiteral( "pdal" ) ); + QCOMPARE( res.at( 0 ).type(), QgsMapLayerType::PointCloudLayer ); + + // make sure result is valid to load layer from + QgsProviderSublayerDetails::LayerOptions options{ QgsCoordinateTransformContext() }; + std::unique_ptr< QgsPointCloudLayer > ml( qgis::down_cast< QgsPointCloudLayer * >( res.at( 0 ).toLayer( options ) ) ); + QVERIFY( ml->isValid() ); +} + void TestQgsPdalProvider::brokenPath() { // test loading a bad layer URI