UI initial implementation for remote ept files

This commit is contained in:
NEDJIMAbelgacem 2021-03-23 16:09:02 +01:00 committed by Martin Dobias
parent e870065342
commit ede1c6394e
30 changed files with 475 additions and 101 deletions

View File

@ -0,0 +1,40 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/pointcloud/qgspointcloudblockhandle.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsPointCloudBlockHandle : QObject
{
%Docstring
Base class for handling loading :py:class:`QgsPointCloudBlock` asynchronously
.. note::
The API is considered EXPERIMENTAL and can be changed without a notice
.. versionadded:: 3.20
%End
%TypeHeaderCode
#include "qgspointcloudblockhandle.h"
%End
public:
QgsPointCloudBlockHandle( const QString &dataType, const QgsPointCloudAttributeCollection &attributes, const QgsPointCloudAttributeCollection &requestedAttributes, QgsTileDownloadManagerReply *tileDownloadManagerReply );
signals:
void blockLoadingSucceeded( QgsPointCloudBlock *block );
void blockLoadingFailed( const QString &errorStr );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/pointcloud/qgspointcloudblockhandle.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -50,6 +50,7 @@ Constructor for LayerOptions with optional ``transformContext``.
explicit QgsPointCloudLayer( const QString &path = QString(),
const QString &baseName = QString(),
const QString &dataSourceType = QString(),
const QString &providerLib = QStringLiteral( "pointcloud" ),
const QgsPointCloudLayer::LayerOptions &options = QgsPointCloudLayer::LayerOptions() );
%Docstring

View File

@ -313,6 +313,7 @@ Creates a new instance of the raster data provider.
.. versionadded:: 3.10
%End
virtual bool createMeshData(
const QgsMesh &mesh,
const QString uri,

View File

@ -127,6 +127,7 @@ Creates new instance of raster data provider
.. versionadded:: 3.10
%End
QList<QPair<QString, QString> > pyramidResamplingMethods( const QString &providerKey );
%Docstring
Returns list of raster pyramid resampling methods

View File

@ -821,7 +821,7 @@ Adds a vector tile layer to the current project.
.. versionadded:: 3.14
%End
virtual QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey ) = 0;
virtual QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &dataSourceType, const QString &baseName, const QString &providerKey ) = 0;
%Docstring
Adds a point cloud layer to the current project.

View File

@ -118,7 +118,7 @@ Emitted when a vector tile layer has been selected for addition.
.. versionadded:: 3.14
%End
void addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey );
void addPointCloudLayer( const QString &url, const QString &baseName, const QString &dataSourceType, const QString &providerKey );
%Docstring
Emitted when a point cloud layer has been selected for addition.

View File

@ -2008,7 +2008,9 @@ void QgisApp::handleDropUriList( const QgsMimeDataUtils::UriList &lst )
}
else if ( u.layerType == QLatin1String( "pointcloud" ) )
{
addPointCloudLayer( uri, u.name, u.providerKey );
QString dataSourceType = QStringLiteral( "remote" );
if ( QFileInfo::exists( uri ) ) dataSourceType = QStringLiteral( "file" );
addPointCloudLayer( uri, u.name, dataSourceType, u.providerKey );
}
else if ( u.layerType == QLatin1String( "vector-tile" ) )
{
@ -5607,9 +5609,9 @@ QgsVectorTileLayer *QgisApp::addVectorTileLayer( const QString &url, const QStri
return addVectorTileLayerPrivate( url, baseName );
}
QgsPointCloudLayer *QgisApp::addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey )
QgsPointCloudLayer *QgisApp::addPointCloudLayer( const QString &url, const QString &baseName, const QString &dataSourceType, const QString &providerKey )
{
return addPointCloudLayerPrivate( url, baseName, providerKey );
return addPointCloudLayerPrivate( url, baseName, dataSourceType, providerKey );
}
QgsVectorTileLayer *QgisApp::addVectorTileLayerPrivate( const QString &url, const QString &baseName, const bool guiWarning )
@ -5654,7 +5656,12 @@ QgsVectorTileLayer *QgisApp::addVectorTileLayerPrivate( const QString &url, cons
return layer.release();
}
QgsPointCloudLayer *QgisApp::addPointCloudLayerPrivate( const QString &uri, const QString &baseName, const QString &providerKey, bool guiWarning )
QgsPointCloudLayer *QgisApp::addPointCloudLayerPrivate(
const QString &uri,
const QString &baseName,
const QString &dataSourceType,
const QString &providerKey,
bool guiWarning )
{
QgsCanvasRefreshBlocker refreshBlocker;
QgsSettings settings;
@ -5669,7 +5676,7 @@ QgsPointCloudLayer *QgisApp::addPointCloudLayerPrivate( const QString &uri, cons
QgsDebugMsgLevel( "completeBaseName: " + base, 2 );
// create the layer
std::unique_ptr<QgsPointCloudLayer> layer( new QgsPointCloudLayer( uri, base, providerKey ) );
std::unique_ptr<QgsPointCloudLayer> layer( new QgsPointCloudLayer( uri, base, dataSourceType, providerKey ) );
if ( !layer || !layer->isValid() )
{
@ -7454,8 +7461,13 @@ bool QgisApp::openLayer( const QString &fileName, bool allowInteractive )
break;
case QgsMapLayerType::PointCloudLayer:
ok = static_cast< bool >( addPointCloudLayerPrivate( fileName, fileInfo.completeBaseName(), candidateProviders.at( 0 ).metadata()->key(), false ) );
break;
{
QString dataSourceType = "remote";
if ( QFileInfo::exists( fileName ) )
dataSourceType = "file";
ok = static_cast< bool >( addPointCloudLayerPrivate( fileName, fileInfo.completeBaseName(), dataSourceType, candidateProviders.at( 0 ).metadata()->key(), false ) );
}
break;
}
}

View File

@ -1161,7 +1161,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
* in the Map Legend so it should be formed in a meaningful way.
* \since QGIS 3.18
*/
QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey );
QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &baseName, const QString &dataSourceType, const QString &providerKey );
/**
* \brief overloaded version of the private addLayer method that takes a list of
@ -2114,6 +2114,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Open a point cloud layer - this is the generic function which takes all parameters
QgsPointCloudLayer *addPointCloudLayerPrivate( const QString &uri,
const QString &dataSourceType,
const QString &baseName,
const QString &providerKey,
bool guiWarning = true );

View File

@ -168,9 +168,9 @@ QgsVectorTileLayer *QgisAppInterface::addVectorTileLayer( const QString &url, co
return qgis->addVectorTileLayer( url, baseName );
}
QgsPointCloudLayer *QgisAppInterface::addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey )
QgsPointCloudLayer *QgisAppInterface::addPointCloudLayer( const QString &url, const QString &dataSourceType, const QString &baseName, const QString &providerKey )
{
return qgis->addPointCloudLayer( url, baseName, providerKey );
return qgis->addPointCloudLayer( url, baseName, dataSourceType, providerKey );
}
bool QgisAppInterface::addProject( const QString &projectName )

View File

@ -71,7 +71,7 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
QgsRasterLayer *addRasterLayer( const QString &url, const QString &baseName, const QString &providerKey ) override;
QgsMeshLayer *addMeshLayer( const QString &url, const QString &baseName, const QString &providerKey ) override;
QgsVectorTileLayer *addVectorTileLayer( const QString &url, const QString &baseName ) override;
QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey ) override;
QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &dataSourceType, const QString &baseName, const QString &providerKey ) override;
bool addProject( const QString &projectName ) override;
bool newProject( bool promptToSaveFlag = false ) override;
void reloadConnections( ) override;

View File

@ -4,12 +4,22 @@
#include <QObject>
#include "qgspointcloudattribute.h"
#include "qgstiledownloadmanager.h"
#define SIP_NO_FILE
class QgsTileDownloadManagerReply;
class QgsPointCloudAttributeCollection;
class QgsPointCloudBlock;
class QgsPointCloudBlockHandle : public QObject
/**
* \ingroup core
* \brief Base class for handling loading QgsPointCloudBlock asynchronously
*
* \note The API is considered EXPERIMENTAL and can be changed without a notice
*
* \since QGIS 3.20
*/
class CORE_EXPORT QgsPointCloudBlockHandle : public QObject
{
Q_OBJECT
public:

View File

@ -32,13 +32,16 @@
#include "qgsmaplayerlegend.h"
#include "qgsmaplayerfactory.h"
#include <QUrl>
#include "qgseptprovider.h"
QgsPointCloudLayer::QgsPointCloudLayer( const QString &path,
const QString &baseName,
const QString &dataSourceType,
const QString &providerLib,
const QgsPointCloudLayer::LayerOptions &options )
: QgsMapLayer( QgsMapLayerType::PointCloudLayer, baseName, path )
, mElevationProperties( new QgsPointCloudLayerElevationProperties( this ) )
, mDataSourceType( dataSourceType )
{
if ( !path.isEmpty() && !providerLib.isEmpty() )
@ -62,7 +65,7 @@ QgsPointCloudLayer *QgsPointCloudLayer::clone() const
options.transformContext = transformContext();
options.skipCrsValidation = true;
QgsPointCloudLayer *layer = new QgsPointCloudLayer( source(), name(), mProviderKey, options );
QgsPointCloudLayer *layer = new QgsPointCloudLayer( source(), name(), mDataSourceType, mProviderKey, options );
QgsMapLayer::clone( layer );
if ( mRenderer )
@ -299,7 +302,7 @@ void QgsPointCloudLayer::setDataSource( const QString &dataSource, const QString
flags |= QgsDataProvider::FlagTrustDataSource;
}
mDataProvider.reset( qobject_cast<QgsPointCloudDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, dataSource, options, flags ) ) );
mDataProvider.reset( qobject_cast<QgsPointCloudDataProvider *>( QgsProviderRegistry::instance()->createEptDataProvider( provider, dataSource, mDataSourceType, options, flags ) ) );
if ( !mDataProvider )
{
QgsDebugMsg( QStringLiteral( "Unable to get point cloud data provider" ) );

View File

@ -90,6 +90,7 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer
*/
explicit QgsPointCloudLayer( const QString &path = QString(),
const QString &baseName = QString(),
const QString &dataSourceType = QString(),
const QString &providerLib = QStringLiteral( "pointcloud" ),
const QgsPointCloudLayer::LayerOptions &options = QgsPointCloudLayer::LayerOptions() );
@ -185,6 +186,8 @@ class CORE_EXPORT QgsPointCloudLayer : public QgsMapLayer
std::unique_ptr<QgsPointCloudRenderer> mRenderer;
QgsPointCloudLayerElevationProperties *mElevationProperties = nullptr;
QString mDataSourceType;
};

View File

@ -17,6 +17,8 @@
#include <QElapsedTimer>
#include <QPointer>
#include <QTimer>
#include <QDebug>
#include "qgspointcloudlayerrenderer.h"
#include "qgspointcloudlayer.h"

View File

@ -16,6 +16,8 @@
***************************************************************************/
#include "qgis.h"
#include "qgslogger.h"
#include "qgsproviderregistry.h"
#include "qgseptprovider.h"
#include "qgseptpointcloudindex.h"
#include "qgsremoteeptpointcloudindex.h"
@ -33,13 +35,14 @@
QgsEptProvider::QgsEptProvider(
const QString &uri,
const QgsDataProvider::ProviderOptions &options,
const QString &dataSourceType,
QgsDataProvider::ReadFlags flags )
: QgsPointCloudDataProvider( uri, options, flags )
{
if ( QFileInfo::exists( uri ) )
mIndex.reset( new QgsEptPointCloudIndex );
else
if ( dataSourceType == QStringLiteral( "remote" ) )
mIndex.reset( new QgsRemoteEptPointCloudIndex );
else
mIndex.reset( new QgsEptPointCloudIndex );
std::unique_ptr< QgsScopedRuntimeProfile > profile;
if ( QgsApplication::profiler()->groupIsActive( QStringLiteral( "projectload" ) ) )
@ -48,6 +51,17 @@ QgsEptProvider::QgsEptProvider(
loadIndex( );
}
QgsEptProvider *QgsEptProvider::create( const QString &providerKey, const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
QgsEptProvider *ret = QgsProviderRegistry::instance()->createEptDataProvider( providerKey, uri, dataSourceType, options, flags );
if ( !ret )
{
QgsDebugMsg( "Cannot resolve 'createEptDataProviderFunction' function in " + providerKey + " provider" );
}
return ret;
}
QgsEptProvider::~QgsEptProvider() = default;
QgsCoordinateReferenceSystem QgsEptProvider::crs() const
@ -130,7 +144,12 @@ QgsEptProviderMetadata::QgsEptProviderMetadata():
QgsEptProvider *QgsEptProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
return new QgsEptProvider( uri, options, flags );
return new QgsEptProvider( uri, options, "", flags );
}
QgsEptProvider *QgsEptProviderMetadata::createEptDataProvider( const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
return new QgsEptProvider( uri, options, dataSourceType, flags );
}
QList<QgsDataItemProvider *> QgsEptProviderMetadata::dataItemProviders() const

View File

@ -38,9 +38,13 @@ class QgsEptProvider: public QgsPointCloudDataProvider
public:
QgsEptProvider( const QString &uri,
const QgsDataProvider::ProviderOptions &providerOptions,
const QString &dataSourceType,
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() );
~QgsEptProvider();
static QgsEptProvider *create( const QString &providerKey, const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags );
QgsCoordinateReferenceSystem crs() const override;
QgsRectangle extent() const override;
@ -68,6 +72,7 @@ class QgsEptProviderMetadata : public QgsProviderMetadata
QgsEptProviderMetadata();
QgsProviderMetadata::ProviderMetadataCapabilities capabilities() const override;
QgsEptProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
QgsEptProvider *createEptDataProvider( const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
QList< QgsDataItemProvider * > dataItemProviders() const override;
int priorityForUri( const QString &uri ) const override;
QList< QgsMapLayerType > validLayerTypesForUri( const QString &uri ) const override;

View File

@ -181,6 +181,15 @@ QgsRasterDataProvider *QgsProviderMetadata::createRasterDataProvider(
return nullptr;
}
QgsEptProvider *QgsProviderMetadata::createEptDataProvider(
const QString &,
const QString &,
const QgsDataProvider::ProviderOptions &,
QgsDataProvider::ReadFlags )
{
return nullptr;
}
bool QgsProviderMetadata::createMeshData(
const QgsMesh &,
const QString,

View File

@ -43,6 +43,7 @@ class QgsTransaction;
class QgsRasterDataProvider;
class QgsMeshDataProvider;
class QgsAbstractDatabaseProviderConnection;
class QgsEptProvider;
struct QgsMesh;
@ -385,6 +386,8 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
const QgsCoordinateReferenceSystem &crs,
const QStringList &createOptions = QStringList() ) SIP_FACTORY;
SIP_SKIP virtual QgsEptProvider *createEptDataProvider( const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) SIP_FACTORY;
/**
* Creates mesh data source, that is the mesh frame stored in file, memory or with other way (depending of the provider)
* \since QGIS 3.16

View File

@ -570,6 +570,15 @@ QgsRasterDataProvider *QgsProviderRegistry::createRasterDataProvider( const QStr
return nullptr;
}
QgsEptProvider *QgsProviderRegistry::createEptDataProvider( const QString &providerKey, const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
if ( meta )
return meta->createEptDataProvider( uri, dataSourceType, options, flags );
return nullptr;
}
QList<QPair<QString, QString> > QgsProviderRegistry::pyramidResamplingMethods( const QString &providerKey )
{
QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );

View File

@ -39,6 +39,7 @@ class QgsCoordinateReferenceSystem;
class QgsDataItemProvider;
class QgsDataItem;
class QgsRasterDataProvider;
class QgsEptProvider;
/**
* \ingroup core
@ -178,6 +179,8 @@ class CORE_EXPORT QgsProviderRegistry
const QgsCoordinateReferenceSystem &crs,
const QStringList &createOptions = QStringList() ) SIP_FACTORY;
SIP_SKIP QgsEptProvider *createEptDataProvider( const QString &providerKey, const QString &uri, const QString &dataSourceType, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) SIP_FACTORY;
/**
* Returns list of raster pyramid resampling methods
*

View File

@ -51,13 +51,13 @@ class QgsOgrSourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsOg
public:
QgsOgrSourceSelect( QWidget *parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags(), QgsProviderRegistry::WidgetMode widgetMode = QgsProviderRegistry::WidgetMode::None );
//! Opens a dialog to select a file datasource*/
//! Opens a dialog to select a file datasource
QStringList openFile();
//! Opens a dialog to select a directory datasource*/
//! Opens a dialog to select a directory datasource
QString openDirectory();
//! Returns a list of selected datasources*/
//! Returns a list of selected datasources
QStringList dataSources();
//! Returns the encoding selected for user*/
//! Returns the encoding selected for user
QString encoding();
//! Returns the connection type
QString dataSourceType();
@ -65,9 +65,9 @@ class QgsOgrSourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsOg
bool isProtocolCloudType();
private:
//! Stores the file vector filters */
//! Stores the file vector filters
QString mVectorFileFilter;
//! Stores the selected datasources */
//! Stores the selected datasources
QStringList mDataSources;
//! Stores the user selected encoding
QString mEnc;

View File

@ -27,6 +27,13 @@ QgsPointCloudSourceSelect::QgsPointCloudSourceSelect( QWidget *parent, Qt::Windo
setupUi( this );
setupButtons( buttonBox );
connect( mRadioSrcFile, &QRadioButton::toggled, this, &QgsPointCloudSourceSelect::radioSrcFile_toggled );
connect( mRadioSrcProtocol, &QRadioButton::toggled, this, &QgsPointCloudSourceSelect::radioSrcProtocol_toggled );
connect( cmbProtocolTypes, &QComboBox::currentTextChanged, this, &QgsPointCloudSourceSelect::cmbProtocolTypes_currentIndexChanged );
radioSrcFile_toggled( true );
setProtocolWidgetsVisibility();
mFileWidget->setDialogTitle( tr( "Open Point Cloud Dataset" ) );
mFileWidget->setFilter( QgsProviderRegistry::instance()->filePointCloudFilters() );
mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles );
@ -35,27 +42,114 @@ QgsPointCloudSourceSelect::QgsPointCloudSourceSelect( QWidget *parent, Qt::Windo
mPath = path;
emit enableButtons( ! mPath.isEmpty() );
} );
connect( protocolURI, &QLineEdit::textChanged, this, [ = ]( const QString & path )
{
mPath = path;
emit enableButtons( ! mPath.isEmpty() );
} );
QStringList protocolTypes = QStringLiteral( "HTTP/HTTPS/FTP,vsicurl" ).split( ';' );
for ( int i = 0; i < protocolTypes.count(); i++ )
{
QString protocolType = protocolTypes.at( i );
if ( ( !protocolType.isEmpty() ) && ( !protocolType.isNull() ) )
cmbProtocolTypes->addItem( protocolType.split( ',' ).at( 0 ) );
}
}
void QgsPointCloudSourceSelect::addButtonClicked()
{
if ( mPath.isEmpty() )
qDebug() << __PRETTY_FUNCTION__ << mDataSourceType;
if ( mDataSourceType == QStringLiteral( "file" ) )
{
QMessageBox::information( this,
tr( "Add Point Cloud Layers" ),
tr( "No layers selected." ) );
return;
qDebug() << __PRETTY_FUNCTION__ << " : " << mPath;
if ( mPath.isEmpty() )
{
QMessageBox::information( this,
tr( "Add Point Cloud Layers" ),
tr( "No layers selected." ) );
return;
}
for ( const QString &path : QgsFileWidget::splitFilePaths( mPath ) )
{
// auto determine preferred provider for each path
const QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProviders = QgsProviderRegistry::instance()->preferredProvidersForUri( mPath );
// maybe we should raise an assert if preferredProviders size is 0 or >1? Play it safe for now...
if ( preferredProviders.empty() )
continue;
qDebug() << "preferredProviders.at( 0 ).metadata()->key(): " << preferredProviders.at( 0 ).metadata()->key();
emit addPointCloudLayer( path, QFileInfo( path ).baseName(), mDataSourceType, preferredProviders.at( 0 ).metadata()->key() ) ;
}
}
for ( const QString &path : QgsFileWidget::splitFilePaths( mPath ) )
else if ( mDataSourceType == QStringLiteral( "remote" ) )
{
// auto determine preferred provider for each path
if ( mPath.isEmpty() )
{
QMessageBox::information( this,
tr( "Add Point Cloud Layers" ),
tr( "No layers selected." ) );
return;
}
// auto determine preferred provider for each path
const QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProviders = QgsProviderRegistry::instance()->preferredProvidersForUri( mPath );
// maybe we should raise an assert if preferredProviders size is 0 or >1? Play it safe for now...
if ( preferredProviders.empty() )
continue;
emit addPointCloudLayer( path, QFileInfo( path ).baseName(), preferredProviders.at( 0 ).metadata()->key() ) ;
if ( !preferredProviders.empty() )
emit addPointCloudLayer( mPath, QFileInfo( mPath ).baseName(), mDataSourceType, preferredProviders.at( 0 ).metadata()->key() ) ;
}
}
void QgsPointCloudSourceSelect::radioSrcFile_toggled( bool checked )
{
if ( checked )
{
fileGroupBox->show();
protocolGroupBox->hide();
mFileWidget->setDialogTitle( tr( "Open Point Cloud Dataset" ) );
mFileWidget->setFilter( QgsProviderRegistry::instance()->filePointCloudFilters() );
mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles );
mDataSourceType = QStringLiteral( "file" );
emit enableButtons( ! mFileWidget->filePath().isEmpty() );
}
}
void QgsPointCloudSourceSelect::radioSrcProtocol_toggled( bool checked )
{
if ( checked )
{
fileGroupBox->hide();
protocolGroupBox->show();
mDataSourceType = QStringLiteral( "remote" );
setProtocolWidgetsVisibility();
emit enableButtons( ! protocolURI->text().isEmpty() );
}
}
void QgsPointCloudSourceSelect::cmbProtocolTypes_currentIndexChanged( const QString &text )
{
Q_UNUSED( text )
setProtocolWidgetsVisibility();
}
void QgsPointCloudSourceSelect::setProtocolWidgetsVisibility()
{
labelProtocolURI->show();
protocolURI->show();
mAuthGroupBox->show();
labelBucket->hide();
mBucket->hide();
labelKey->hide();
mKey->hide();
mAuthWarning->hide();
}

View File

@ -44,9 +44,16 @@ class QgsPointCloudSourceSelect : public QgsAbstractDataSourceWidget, private Ui
//! Determines the tables the user selected and closes the dialog
void addButtonClicked() override;
private slots:
void radioSrcProtocol_toggled( bool checked );
void radioSrcFile_toggled( bool checked );
void cmbProtocolTypes_currentIndexChanged( const QString &text );
//! Sets protocol-related widget visibility
void setProtocolWidgetsVisibility();
private:
QString mPath;
QString mDataSourceType;
};
///@endcond

View File

@ -726,7 +726,7 @@ class GUI_EXPORT QgisInterface : public QObject
* Adds a point cloud layer to the current project.
* \since QGIS 3.18
*/
virtual QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey ) = 0;
virtual QgsPointCloudLayer *addPointCloudLayer( const QString &url, const QString &dataSourceType, const QString &baseName, const QString &providerKey ) = 0;
//! Adds (opens) a project
virtual bool addProject( const QString &project ) = 0;

View File

@ -131,7 +131,7 @@ class GUI_EXPORT QgsAbstractDataSourceWidget : public QDialog
* Emitted when a point cloud layer has been selected for addition.
* \since QGIS 3.18
*/
void addPointCloudLayer( const QString &url, const QString &baseName, const QString &providerKey );
void addPointCloudLayer( const QString &url, const QString &baseName, const QString &dataSourceType, const QString &providerKey );
/**
* Emitted when one or more OGR supported layers are selected for addition

View File

@ -223,7 +223,10 @@ void QgsBrowserLayerProperties::setItem( QgsDataItem *item )
QgsDebugMsgLevel( QStringLiteral( "creating point cloud layer" ), 2 );
QgsPointCloudLayer::LayerOptions options { QgsProject::instance()->transformContext() };
options.skipCrsValidation = true;
mLayer = std::make_unique< QgsPointCloudLayer >( layerItem->uri(), layerItem->name(), layerItem->providerKey(), options );
QString dataSourceType = QStringLiteral( "remote" );
if ( QFileInfo::exists( layerItem->uri() ) )
dataSourceType = QStringLiteral( "file" );
mLayer = std::make_unique< QgsPointCloudLayer >( layerItem->uri(), layerItem->name(), dataSourceType, layerItem->providerKey(), options );
break;
}

View File

@ -137,7 +137,7 @@ class GUI_EXPORT QgsDataSourceManagerDialog : public QgsOptionsDialogBase, priva
* Emitted when a point cloud layer was selected for addition: for signal forwarding to QgisApp
* \since QGIS 3.18
*/
void addPointCloudLayer( const QString &pointCloudLayerPath, const QString &baseName, const QString &providerKey );
void addPointCloudLayer( const QString &pointCloudLayerPath, const QString &baseName, const QString &dataSourceType, const QString &providerKey );
//! Replace the selected layer by a vector layer defined by uri, layer name, data source uri
void replaceSelectedVectorLayer( const QString &oldId, const QString &uri, const QString &layerName, const QString &provider );

View File

@ -81,6 +81,7 @@
<class>QgsFileWidget</class>
<extends>QWidget</extends>
<header>qgsfilewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>119</height>
<width>584</width>
<height>495</height>
</rect>
</property>
<property name="windowTitle">
@ -23,37 +23,174 @@
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="fileGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Source</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Point cloud dataset</string>
</property>
</widget>
</item>
<item>
<widget class="QgsFileWidget" name="mFileWidget" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QGroupBox" name="protocolGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Protocol</string>
</property>
<layout class="QGridLayout" name="gridLayout_21">
<item row="0" column="1">
<widget class="QComboBox" name="cmbProtocolTypes"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelProtocolURI">
<property name="text">
<string>&amp;URI</string>
</property>
<property name="buddy">
<cstring>protocolURI</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="protocolURI"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelBucket">
<property name="text">
<string>Bucket or container</string>
</property>
<property name="buddy">
<cstring>mBucket</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="mBucket"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelKey">
<property name="text">
<string>Object key</string>
</property>
<property name="buddy">
<cstring>mKey</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="mKey"/>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="mAuthWarning">
<property name="text">
<string>…</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="mAuthGroupBox">
<property name="title">
<string>Authentication</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QgsAuthSettingsWidget" name="mAuthSettingsProtocol" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Help</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="srcGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Source Type</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout1_2">
<item>
<widget class="QRadioButton" name="mRadioSrcFile">
<property name="text">
<string>F&amp;ile</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="mRadioSrcProtocol">
<property name="text">
<string>Protoco&amp;l: HTTP(S), cloud, etc.</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -66,13 +203,34 @@
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::NoButton</set>
<item row="1" column="0">
<widget class="QGroupBox" name="fileGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Source</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Point cloud dataset(s)</string>
</property>
</widget>
</item>
<item>
<widget class="QgsFileWidget" name="mFileWidget" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
@ -81,28 +239,15 @@
<class>QgsFileWidget</class>
<extends>QWidget</extends>
<header>qgsfilewidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsAuthSettingsWidget</class>
<extends>QWidget</extends>
<header>auth/qgsauthsettingswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsPointCloudSourceSelectBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>518</x>
<y>510</y>
</hint>
<hint type="destinationlabel">
<x>551</x>
<y>370</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -162,6 +162,7 @@ void TestQgsPdalProvider::brokenPath()
std::unique_ptr< QgsPointCloudLayer > layer = std::make_unique< QgsPointCloudLayer >(
QStringLiteral( "not valid" ),
QStringLiteral( "layer" ),
QStringLiteral( "file" ),
QStringLiteral( "pdal" ) );
QVERIFY( !layer->isValid() );
}
@ -174,6 +175,7 @@ void TestQgsPdalProvider::validLayer()
std::unique_ptr< QgsPointCloudLayer > layer = std::make_unique< QgsPointCloudLayer >(
mTestDataDir + QStringLiteral( "point_clouds/las/cloud.las" ),
QStringLiteral( "layer" ),
QStringLiteral( "file" ),
QStringLiteral( "pdal" ),
options
);