Implement querySublayers for pdal provider

This commit is contained in:
Nyall Dawson 2021-07-23 11:28:57 +10:00
parent c74f42cd58
commit dd9eb90a43
3 changed files with 54 additions and 2 deletions

View File

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

View File

@ -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;
};

View File

@ -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<QgsProviderRegistry::ProviderCandidateDetails> 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