Skip to content

Commit

Permalink
Implement querySublayers for pdal provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 23, 2021
1 parent c74f42c commit dd9eb90
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
24 changes: 23 additions & 1 deletion src/providers/pdal/qgspdalprovider.cpp
Expand Up @@ -26,6 +26,8 @@
#include "qgspdaleptgenerationtask.h"
#include "qgseptpointcloudindex.h"
#include "qgstaskmanager.h"
#include "qgsprovidersublayerdetails.h"
#include "qgsproviderutils.h"

#include <pdal/io/LasReader.hpp>
#include <pdal/io/LasHeader.hpp>
Expand Down Expand Up @@ -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<QgsDataItemProvider *> QgsPdalProviderMetadata::dataItemProviders() const
Expand Down Expand Up @@ -322,6 +325,25 @@ QList<QgsMapLayerType> QgsPdalProviderMetadata::validLayerTypesForUri( const QSt
return QList<QgsMapLayerType>();
}

QList<QgsProviderSublayerDetails> 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 )
Expand Down
1 change: 1 addition & 0 deletions src/providers/pdal/qgspdalprovider.h
Expand Up @@ -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;
};
Expand Down
31 changes: 30 additions & 1 deletion tests/src/providers/testqgspdalprovider.cpp
Expand Up @@ -32,6 +32,7 @@
#include "qgsmaplayer.h"
#include "qgspointcloudlayer.h"
#include "qgspdaleptgenerationtask.h"
#include "qgsprovidersublayerdetails.h"

/**
* \ingroup UnitTests
Expand All @@ -52,6 +53,7 @@ class TestQgsPdalProvider : public QObject
void decodeUri();
void layerTypesForUri();
void preferredUri();
void querySublayers();
void brokenPath();
void validLayer();
void testEptGeneration();
Expand Down Expand Up @@ -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<QgsProviderRegistry::ProviderCandidateDetails> candidates = QgsProviderRegistry::instance()->preferredProvidersForUri( QStringLiteral( "/home/test/cloud.las" ) );
QCOMPARE( candidates.size(), 1 );
QCOMPARE( candidates.at( 0 ).metadata()->key(), QStringLiteral( "pdal" ) );
Expand All @@ -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
Expand Down

0 comments on commit dd9eb90

Please sign in to comment.