33 #include "providers/gdal/qgsgdalprovider.h"
34 #include "providers/ogr/qgsogrprovidermetadata.h"
35 #include "providers/ogr/qgsogrprovider.h"
36 #include "providers/meshmemory/qgsmeshmemorydataprovider.h"
39 #include "providers/ept/qgseptprovider.h"
43 #include "providers/copc/qgscopcprovider.h"
49 #ifdef HAVE_STATIC_PROVIDERS
50 #include "qgswmsprovider.h"
51 #include "qgswcsprovider.h"
52 #include "qgsdelimitedtextprovider.h"
53 #include "qgsafsprovider.h"
54 #include "qgsamsprovider.h"
55 #ifdef HAVE_SPATIALITE
56 #include "qgsspatialiteprovider.h"
57 #include "qgswfsprovider.h"
58 #include "qgsoapifprovider.h"
59 #include "qgsvirtuallayerprovider.h"
61 #ifdef HAVE_POSTGRESQL
62 #include "qgspostgresprovider.h"
69 #include <QRegularExpression>
78 const QMutexLocker locker( &sMutex );
98 const QString &providerKey )
101 const QgsProviderRegistry::Providers::const_iterator i =
102 metaData.find( providerKey );
104 if ( i != metaData.end() )
110 for (
auto it = metaData.begin(); it != metaData.end(); ++it )
112 if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
119 QgsProviderRegistry::QgsProviderRegistry(
const QString &pluginPath )
127 char **argv = qApp->argv();
128 QString appDir = argv[0];
129 int bin = appDir.findRev(
"/bin", -1,
false );
130 QString baseDir = appDir.left( bin );
131 QString mLibraryDirectory = baseDir +
"/lib";
135 mLibraryDirectory.setPath( pluginPath );
143 bool matchesUri(
const QString &uri )
const override
145 const QFileInfo fi( uri );
146 if ( fi.suffix().compare( QLatin1String(
"las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String(
"laz" ), Qt::CaseInsensitive ) == 0 )
155 QObject::tr(
"LAS and LAZ files cannot be opened by this QGIS install." ),
159 res.
detailedWarning = QObject::tr(
"The installer used to install this version of QGIS does "
160 "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
161 "obtain one of the alternative installers from https://qgis.org which has point "
162 "cloud support enabled." );
164 res.
detailedWarning = QObject::tr(
"This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
171 void QgsProviderRegistry::init()
177 mProviders[ QgsMemoryProvider::providerKey() ] =
new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
181 mProviders[ QgsMeshMemoryDataProvider::providerKey() ] =
new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
186 mProviders[ QgsGdalProvider::providerKey() ] =
new QgsGdalProviderMetadata();
190 mProviders[ QgsOgrProvider::providerKey() ] =
new QgsOgrProviderMetadata();
195 mProviders[ vt->
key() ] = vt;
201 mProviders[ pc->
key() ] = pc;
208 mProviders[ pc->
key() ] = pc;
213 #ifdef HAVE_STATIC_PROVIDERS
214 mProviders[ QgsWmsProvider::providerKey() ] =
new QgsWmsProviderMetadata();
215 mProviders[ QgsWcsProvider::providerKey() ] =
new QgsWcsProviderMetadata();
216 mProviders[ QgsDelimitedTextProvider::providerKey() ] =
new QgsDelimitedTextProviderMetadata();
217 mProviders[ QgsAfsProvider::providerKey() ] =
new QgsAfsProviderMetadata();
218 mProviders[ QgsAmsProvider::providerKey() ] =
new QgsAmsProviderMetadata();
219 #ifdef HAVE_SPATIALITE
220 mProviders[ QgsSpatiaLiteProvider::providerKey() ] =
new QgsSpatiaLiteProviderMetadata();
221 mProviders[ QgsWFSProvider::providerKey() ] =
new QgsWfsProviderMetadata();
222 mProviders[ QgsOapifProvider::providerKey() ] =
new QgsOapifProviderMetadata();
223 mProviders[ QgsVirtualLayerProvider::providerKey() ] =
new QgsVirtualLayerProviderMetadata();
225 #ifdef HAVE_POSTGRESQL
226 mProviders[ QgsPostgresProvider::providerKey() ] =
new QgsPostgresProviderMetadata();
231 #ifdef HAVE_STATIC_PROVIDERS
232 QgsDebugMsg( QStringLiteral(
"Forced only static providers" ) );
236 mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
237 mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
239 #if defined(Q_OS_WIN) || defined(__CYGWIN__)
240 mLibraryDirectory.setNameFilters( QStringList(
"*.dll" ) );
241 #elif defined(ANDROID)
242 mLibraryDirectory.setNameFilters( QStringList(
"*provider_*.so" ) );
244 mLibraryDirectory.setNameFilters( QStringList( QStringLiteral(
"*.so" ) ) );
247 QgsDebugMsgLevel( QStringLiteral(
"Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
249 if ( mLibraryDirectory.count() == 0 )
251 QgsDebugMsg( QStringLiteral(
"No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
255 const QString filePattern = getenv(
"QGIS_PROVIDER_FILE" );
256 QRegularExpression fileRegexp;
257 if ( !filePattern.isEmpty() )
259 fileRegexp.setPattern( filePattern );
262 typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
264 const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
265 for (
const QFileInfo &fi : constEntryInfoList )
267 if ( !filePattern.isEmpty() )
269 if ( fi.fileName().indexOf( fileRegexp ) == -1 )
271 QgsDebugMsg(
"provider " + fi.fileName() +
" skipped because doesn't match pattern " + filePattern );
277 if ( fi.fileName().contains( QStringLiteral(
"authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
283 QLibrary myLib( fi.filePath() );
286 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
290 bool libraryLoaded {
false };
291 QFunctionPointer func = myLib.resolve( QStringLiteral(
"providerMetadataFactory" ).toLatin1().data() );
292 factory_function *
function =
reinterpret_cast< factory_function *
>(
cast_to_fptr( func ) );
298 if ( findMetadata_( mProviders, meta->
key() ) )
300 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
305 mProviders[meta->
key()] = meta;
306 libraryLoaded =
true;
311 QFunctionPointer multi_func = myLib.resolve( QStringLiteral(
"multipleProviderMetadataFactory" ).toLatin1().data() );
312 multiple_factory_function *multi_function =
reinterpret_cast< multiple_factory_function *
>(
cast_to_fptr( multi_func ) );
313 if ( multi_function )
315 std::vector<QgsProviderMetadata *> *metadatas = multi_function();
316 for (
const auto meta : *metadatas )
318 if ( findMetadata_( mProviders, meta->
key() ) )
320 QgsDebugMsg( QStringLiteral(
"Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->
key() ) );
325 mProviders[meta->
key()] = meta;
326 libraryLoaded =
true;
332 if ( ! libraryLoaded )
334 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
339 QgsDebugMsg( QStringLiteral(
"Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg(
providerList().join(
';' ) ) );
341 QStringList pointCloudWildcards;
342 QStringList pointCloudFilters;
345 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
347 const QString &key = it->first;
375 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split(
";;" ).count() ), 2 );
383 QgsDebugMsgLevel( QStringLiteral(
"Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split(
";;" ).count() ), 2 );
392 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
393 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), QString::SkipEmptyParts );
395 const QStringList filters =
filePointCloudFilters.split( QStringLiteral(
";;" ), Qt::SkipEmptyParts );
397 for (
const QString &filter : filters )
399 pointCloudFilters.append( filter );
408 if ( !pointCloudFilters.empty() )
410 pointCloudFilters.insert( 0, QObject::tr(
"All Supported Files" ) + QStringLiteral(
" (%1)" ).arg( pointCloudWildcards.join(
' ' ) ) );
411 pointCloudFilters.insert( 1, QObject::tr(
"All Files" ) + QStringLiteral(
" (*.*)" ) );
412 mPointCloudFileFilters = pointCloudFilters.join( QLatin1String(
";;" ) );
416 mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
419 mDirectoryDrivers = QgsOgrProviderUtils::directoryDrivers();
422 mProtocolDrivers = QgsOgrProviderUtils::protocolDrivers();
429 void QgsProviderRegistry::clean()
432 if ( QgsProject::sProject )
435 Providers::const_iterator it = mProviders.begin();
437 while ( it != mProviders.end() )
440 it->second->cleanupProvider();
447 bool QgsProviderRegistry::exists()
449 return static_cast< bool >( sInstance );
454 qDeleteAll( mUnusableUriHandlers );
457 if ( sInstance ==
this )
477 Providers::const_iterator it = mProviders.begin();
479 if ( mProviders.empty() )
480 return QObject::tr(
"No data provider plugins are available. No vector layers can be loaded" );
485 list += QLatin1String(
"<ol>" );
487 while ( it != mProviders.end() )
490 list += QLatin1String(
"<li>" );
492 list += it->second->description();
495 list += QLatin1String(
"<br></li>" );
503 list += QLatin1String(
"</ol>" );
510 mLibraryDirectory = path;
517 return mLibraryDirectory;
530 QgsDataProvider::ReadFlags flags )
547 const QList< QgsDataItemProvider * > itemProviders =
dataItemProviders( providerKey );
552 ret = ret | itemProvider->capabilities();
563 return QVariantMap();
580 bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
581 QString &errorMessage,
582 const QMap<QString, QVariant> *options )
586 return meta->
createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
589 errorMessage = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
590 return Qgis::VectorExportResult::ErrorInvalidProvider;
597 const QStringList &createOptions )
612 return QList<QPair<QString, QString> >();
621 return QList<QgsDataItemProvider *>();
624 int QgsProviderRegistry::listStyles(
const QString &providerKey,
const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
630 res = meta->
listStyles( uri, ids, names, descriptions, errCause );
634 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
645 return meta->
styleExists( uri, styleId, errorCause );
649 errorCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
664 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
671 const bool ret(
false );
678 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
684 const QString &sldStyle,
const QString &styleName,
const QString &styleDescription,
685 const QString &uiFileContent,
bool useAsDefault, QString &errCause )
690 ret = meta->
saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
691 uiFileContent, useAsDefault, errCause );
694 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
707 errCause = QObject::tr(
"Unable to load %1 provider" ).arg( providerKey );
714 errorMessage.clear();
727 return meta->
createDb( dbPath, errCause );
730 errCause = QStringLiteral(
"Resolving createDb(...) failed" );
747 Q_UNUSED( providerKey );
750 Q_UNUSED( widgetMode );
751 QgsDebugMsg(
"deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
756 QString
const &functionName )
const
759 const QString lib =
library( providerKey );
764 QLibrary myLib( lib );
766 QgsDebugMsg(
"Library name is " + myLib.fileName() );
770 return myLib.resolve( functionName.toLatin1().data() );
774 QgsDebugMsg(
"Cannot load library: " + myLib.errorString() );
782 const QString lib =
library( providerKey );
787 std::unique_ptr< QLibrary > myLib(
new QLibrary( lib ) );
789 QgsDebugMsg(
"Library name is " + myLib->fileName() );
792 return myLib.release();
794 QgsDebugMsg(
"Cannot load library: " + myLib->errorString() );
801 QgsDebugMsg(
"deprecated - use QgsGui::providerGuiRegistry() instead." );
820 QgsDebugMsgLevel( QStringLiteral(
"Trying to register a null metadata provider!" ), 2 );
827 return mVectorFileFilters;
832 return mRasterFileFilters;
837 return mMeshFileFilters;
842 return mMeshDatasetFileFilters;
847 return mPointCloudFileFilters;
852 return mDatabaseDrivers;
857 return mDirectoryDrivers;
862 return mProtocolDrivers;
868 for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
870 lst.append( it->first );
877 return findMetadata_( mProviders, providerKey );
882 QList< QgsProviderRegistry::ProviderCandidateDetails > res;
884 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
889 const int thisProviderPriority = it->second->priorityForUri( uri );
890 if ( thisProviderPriority == 0 )
893 if ( thisProviderPriority > maxPriority )
896 maxPriority = thisProviderPriority;
898 if ( thisProviderPriority == maxPriority )
908 mUnusableUriHandlers << handler;
916 if ( handler->matchesUri( uri ) )
918 details = handler->details( uri );
928 if ( providers.empty() )
933 if ( provider.metadata()->key() == providerKey )
941 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
943 if ( it->second->uriIsBlocklisted( uri ) )
955 QList<QgsProviderSublayerDetails> res;
956 for (
auto it = mProviders.begin(); it != mProviders.end(); ++it )
962 res.append( it->second->querySublayers( uri, flags, feedback ) );
VectorExportResult
Vector layer export result codes.
DataType
Raster data types.
This class represents a coordinate reference system (CRS).
This is the interface for those who want to add custom data items to the browser tree.
Abstract base class for spatial data provider implementations.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Container of fields for a vector layer.
static QString wildcardsFromFilter(const QString &filter)
Given a filter string like "GeoTIFF Files (*.tiff *.tif)", extracts the wildcard portion of this filt...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Custom exception class which is raised when an operation is not supported.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void removeAllMapLayers()
Removes all registered layers.
Contains information pertaining to a candidate provider.
Contains information about unusable URIs which aren't handled by any registered providers.
QString detailedWarning
Contains a longer, user-friendly, translated message advising why the URI is not usable.
An interface used to handle unusable URIs which aren't handled by any registered providers,...
virtual UnusableUriDetails details(const QString &uri) const =0
Returns the details for advising the user why the uri is not usable.
virtual bool matchesUri(const QString &uri) const =0
Returns true if the handle is an unusable URI handler for the specified uri.
A registry / canonical manager of data providers.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags flags=QgsDataProvider::ReadFlags())
Creates a new instance of a provider.
std::map< QString, QgsProviderMetadata * > Providers
Type for data provider metadata associative container.
bool styleExists(const QString &providerKey, const QString &uri, const QString &styleId, QString &errorCause)
Returns true if a layer style with the specified styleId exists in the provider defined by providerKe...
QString loadStyle(const QString &providerKey, const QString &uri, QString &errCause)
Loads a layer style defined by uri.
QString getStyleById(const QString &providerKey, const QString &uri, const QString &styleId, QString &errCause)
Gets a layer style defined by styleId.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
void setLibraryDirectory(const QDir &path)
Sets library directory where to search for plugins.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, QgsWkbTypes::Type wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options)
Creates new empty vector layer.
QgsTransaction * createTransaction(const QString &providerKey, const QString &connString)
Returns new instance of transaction.
QList< QgsProviderSublayerDetails > querySublayers(const QString &uri, Qgis::SublayerQueryFlags flags=Qgis::SublayerQueryFlags(), QgsFeedback *feedback=nullptr) const
Queries the specified uri and returns a list of any valid sublayers found in the dataset which can be...
Q_DECL_DEPRECATED void registerGuis(QWidget *widget)
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
WidgetMode
Different ways a source select dialog can be used.
QString protocolDrivers() const
Returns a string containing the available protocol drivers.
QList< QgsProviderRegistry::ProviderCandidateDetails > preferredProvidersForUri(const QString &uri) const
Returns the details for the preferred provider(s) for opening the specified uri.
Q_DECL_DEPRECATED QString library(const QString &providerKey) const
Returns path for the library of the provider.
QString databaseDrivers() const
Returns a string containing the available database drivers.
QString encodeUri(const QString &providerKey, const QVariantMap &parts)
Reassembles a provider data source URI from its component paths (e.g.
QList< QgsDataItemProvider * > dataItemProviders(const QString &providerKey) const
Returns list of data item providers of the provider.
QgsRasterDataProvider * createRasterDataProvider(const QString &providerKey, const QString &uri, const QString &format, int nBands, Qgis::DataType type, int width, int height, double *geoTransform, const QgsCoordinateReferenceSystem &crs, const QStringList &createOptions=QStringList())
Creates new instance of raster data provider.
QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns list of raster pyramid resampling methods.
bool uriIsBlocklisted(const QString &uri) const
Returns true if the specified uri is known by any registered provider to be something which should be...
Q_DECL_DEPRECATED QLibrary * createProviderLibrary(const QString &providerKey) const
Returns a new QLibrary for the specified providerKey.
bool handleUnusableUri(const QString &uri, UnusableUriDetails &details) const
Returns true if the specified uri can potentially be handled by QGIS, if additional dependencies or b...
QString fileVectorFilters() const
Returns a file filter string for supported vector files.
QString fileRasterFilters() const
Returns a file filter string for supported raster files.
QString fileMeshFilters() const
Returns a file filter string for supported mesh files.
QString pluginList(bool asHtml=false) const
Returns list of provider plugins found.
Q_DECL_DEPRECATED int providerCapabilities(const QString &providerKey) const
Returns the provider capabilities.
bool shouldDeferUriForOtherProviders(const QString &uri, const QString &providerKey) const
Returns true if the provider with matching providerKey should defer handling of the specified uri to ...
bool deleteStyleById(const QString &providerKey, const QString &uri, const QString &styleId, QString &errCause)
Deletes a layer style defined by styleId.
QStringList providerList() const
Returns list of available providers by their keys.
QString fileMeshDatasetFilters() const
Returns a file filter string for supported mesh dataset files.
QDir libraryDirectory() const
Returns the library directory where plugins are found.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
int listStyles(const QString &providerKey, const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause)
Lists stored layer styles in the provider defined by providerKey and uri.
bool createDb(const QString &providerKey, const QString &dbPath, QString &errCause)
Creates database by the provider on the path.
bool saveStyle(const QString &providerKey, const QString &uri, const QString &qmlStyle, const QString &sldStyle, const QString &styleName, const QString &styleDescription, const QString &uiFileContent, bool useAsDefault, QString &errCause)
Saves a layer style to provider.
bool registerProvider(QgsProviderMetadata *providerMetadata)
register a new vector data provider from its providerMetadata
Q_DECL_DEPRECATED QFunctionPointer function(const QString &providerKey, const QString &functionName) const
Gets pointer to provider function.
QString directoryDrivers() const
Returns a string containing the available directory drivers.
bool saveLayerMetadata(const QString &providerKey, const QString &uri, const QgsLayerMetadata &metadata, QString &errorMessage) SIP_THROW(QgsNotSupportedException)
Saves metadata to the layer corresponding to the specified uri.
bool registerUnusableUriHandler(UnusableUriHandlerInterface *handler)
Registers an unusable URI handler, used to handle unusable URIs which aren't handled by any registere...
Q_DECL_DEPRECATED QWidget * createSelectionWidget(const QString &providerKey, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::None)
Returns a new widget for selecting layers from a provider.
QString filePointCloudFilters() const
Returns a file filter string for supported point clouds.
Base class for raster data providers.
Scoped object for logging of the runtime for a single operation or group of operations.
This class allows including a set of layers in a database-side transaction, provided the layer data p...
Type
The WKB type describes the number of dimensions a geometry has.
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
void cleanupProviderFunction_t()
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.