Move qgsVsiPrefix to QgsGdalUtils::vsiPrefixForPath

This commit is contained in:
Nyall Dawson 2023-06-20 10:55:42 +10:00
parent 2b2dabaf93
commit a4843be25b
14 changed files with 85 additions and 39 deletions

View File

@ -47,7 +47,12 @@ Constructor
static QStringList sProviderNames;
static QString vsiPrefix( const QString &uri );
static QString vsiPrefix( const QString &uri ) /Deprecated/;
%Docstring
.. deprecated::
Will be removed in QGIS 4.0
%End
static QgsDataItem *itemFromPath( QgsDataItem *parent, const QString &path, const QString &name ) /Factory/;
%Docstring

View File

@ -59,6 +59,7 @@
#include "qgsfieldformatter.h"
#include "qgsabstractdatabaseproviderconnection.h"
#include "qgsrasterlayerelevationproperties.h"
#include "qgsgdalutils.h"
#include <QObject>
#include <QMessageBox>
@ -283,7 +284,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::addOgrVectorLayers( const QStringLis
baseName = QgsProviderUtils::suggestLayerNameFromFilePath( srcWithoutLayername );
// if needed prompt for zipitem layers
QString vsiPrefix = qgsVsiPrefix( uri );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( uri );
if ( ! uri.startsWith( QLatin1String( "/vsi" ), Qt::CaseInsensitive ) &&
( vsiPrefix == QLatin1String( "/vsizip/" ) || vsiPrefix == QLatin1String( "/vsitar/" ) ) )
{
@ -871,7 +872,7 @@ QList< QgsMapLayer * > QgsAppLayerHandling::openLayer( const QString &fileName,
CPLPushErrorHandler( CPLQuietErrorHandler );
// if needed prompt for zipitem layers
QString vsiPrefix = qgsVsiPrefix( fileName );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( fileName );
if ( vsiPrefix == QLatin1String( "/vsizip/" ) || vsiPrefix == QLatin1String( "/vsitar/" ) )
{
if ( askUserForZipItemLayers( fileName, {} ) )
@ -1055,7 +1056,7 @@ QList<QgsMapLayer *> QgsAppLayerHandling::addGdalRasterLayers( const QStringList
QString errMsg;
// if needed prompt for zipitem layers
QString vsiPrefix = qgsVsiPrefix( uri );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( uri );
if ( ( !uri.startsWith( QLatin1String( "/vsi" ), Qt::CaseInsensitive ) || uri.endsWith( QLatin1String( ".zip" ) ) || uri.endsWith( QLatin1String( ".tar" ) ) ) &&
( vsiPrefix == QLatin1String( "/vsizip/" ) || vsiPrefix == QLatin1String( "/vsitar/" ) ) )
{

View File

@ -27,9 +27,7 @@
#include "qgsrelationshipsitem.h"
#include "qgsproviderutils.h"
#include "qgsprovidermetadata.h"
#if GDAL_VERSION_NUM < GDAL_COMPUTE_VERSION(3,4,0)
#include "qgsgdalutils.h"
#endif
#include <QUrlQuery>
//
@ -221,7 +219,7 @@ QgsFileDataCollectionItem::QgsFileDataCollectionItem( QgsDataItem *parent, const
else
setCapabilities( Qgis::BrowserItemCapability::Fast | Qgis::BrowserItemCapability::Fertile );
if ( !qgsVsiPrefix( path ).isEmpty() )
if ( !QgsGdalUtils::vsiPrefixForPath( path ).isEmpty() )
{
mIconName = QStringLiteral( "/mIconZip.svg" );
}

View File

@ -20,6 +20,7 @@
#include "qgsdataitemprovider.h"
#include "qgsdataitemproviderregistry.h"
#include "qgssettings.h"
#include "qgsgdalutils.h"
#include <QFileInfo>
@ -82,6 +83,11 @@ QgsMimeDataUtils::UriList QgsZipItem::mimeUris() const
return { u };
}
QString QgsZipItem::vsiPrefix( const QString &uri )
{
return QgsGdalUtils::vsiPrefixForPath( uri );
}
QVector<QgsDataItem *> QgsZipItem::createChildren()
{
QVector<QgsDataItem *> children;

View File

@ -60,7 +60,10 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem
static QVector<dataItem_t *> sDataItemPtr SIP_SKIP;
static QStringList sProviderNames;
static QString vsiPrefix( const QString &uri ) { return qgsVsiPrefix( uri ); }
/**
* \deprecated Will be removed in QGIS 4.0
*/
Q_DECL_DEPRECATED static QString vsiPrefix( const QString &uri ) SIP_DEPRECATED;
/**
* Creates a new data item from the specified path.

View File

@ -2874,7 +2874,7 @@ bool QgsGdalProvider::isValidRasterFileName( QString const &fileNameQString, QSt
// Try to open using VSIFileHandler (see qgsogrprovider.cpp)
// TODO suppress error messages and report in debug, like in OGR provider
QString vsiPrefix = qgsVsiPrefix( fileName );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( fileName );
if ( !vsiPrefix.isEmpty() )
{
if ( !fileName.startsWith( vsiPrefix ) )
@ -3216,7 +3216,7 @@ bool QgsGdalProvider::initIfNeeded()
QString gdalUri = dataSourceUri( true );
// Try to open using VSIFileHandler (see qgsogrprovider.cpp)
QString vsiPrefix = qgsVsiPrefix( gdalUri );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( gdalUri );
if ( !vsiPrefix.isEmpty() )
{
if ( !gdalUri.startsWith( vsiPrefix ) )
@ -4228,7 +4228,7 @@ QList<QgsProviderSublayerDetails> QgsGdalProviderMetadata::querySublayers( const
QVariantMap uriParts = decodeUri( gdalUri );
// Try to open using VSIFileHandler
QString vsiPrefix = qgsVsiPrefix( gdalUri );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( gdalUri );
if ( !vsiPrefix.isEmpty() )
{
if ( !gdalUri.startsWith( vsiPrefix ) )

View File

@ -25,6 +25,7 @@
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgsgdalproviderbase.h"
#include "qgsgdalutils.h"
#include "qgssettings.h"
#include <mutex>
@ -401,7 +402,7 @@ QVariantMap QgsGdalProviderBase::decodeGdalUri( const QString &uri )
authcfg = match.captured( 1 );
}
QString vsiPrefix = qgsVsiPrefix( path );
QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( path );
QString vsiSuffix;
if ( path.startsWith( vsiPrefix, Qt::CaseInsensitive ) )
{

View File

@ -3592,7 +3592,7 @@ void QgsOgrProvider::open( OpenMode mode )
// Try to open using VSIFileHandler
// see http://trac.osgeo.org/gdal/wiki/UserDocs/ReadInZip
QString vsiPrefix = qgsVsiPrefix( dataSourceUri( true ) );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( dataSourceUri( true ) );
if ( !vsiPrefix.isEmpty() || mFilePath.startsWith( QLatin1String( "/vsicurl/" ) ) )
{
// GDAL>=1.8.0 has write support for zip, but read and write operations

View File

@ -152,7 +152,7 @@ QVariantMap QgsOgrProviderMetadata::decodeUri( const QString &uri ) const
authcfg = match.captured( 1 );
}
QString vsiPrefix = qgsVsiPrefix( path );
QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( path );
QString vsiSuffix;
if ( path.startsWith( vsiPrefix, Qt::CaseInsensitive ) )
{
@ -1185,7 +1185,7 @@ QList<QgsProviderSublayerDetails> QgsOgrProviderMetadata::querySublayers( const
QVariantMap uriParts = decodeUri( uri );
// Try to open using VSIFileHandler
QString vsiPrefix = qgsVsiPrefix( uriParts.value( QStringLiteral( "path" ) ).toString() );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( uriParts.value( QStringLiteral( "path" ) ).toString() );
if ( !vsiPrefix.isEmpty() && uriParts.value( QStringLiteral( "vsiPrefix" ) ).toString().isEmpty() )
{
if ( !uri.startsWith( vsiPrefix ) )

View File

@ -27,6 +27,7 @@
#include <QDateTime>
#include "qgsconfig.h"
#include "qgslogger.h"
#include "qgsgdalutils.h"
#include "qgswkbtypes.h"
#include <gdal.h>
@ -191,27 +192,7 @@ bool qgsVariantGreaterThan( const QVariant &lhs, const QVariant &rhs )
QString qgsVsiPrefix( const QString &path )
{
if ( path.startsWith( QLatin1String( "/vsizip/" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsizip/" );
else if ( path.endsWith( QLatin1String( ".shp.zip" ), Qt::CaseInsensitive ) )
{
// GDAL 3.1 Shapefile driver directly handles .shp.zip files
if ( GDALIdentifyDriverEx( path.toUtf8().constData(), GDAL_OF_VECTOR, nullptr, nullptr ) )
return QString();
return QStringLiteral( "/vsizip/" );
}
else if ( path.endsWith( QLatin1String( ".zip" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsizip/" );
else if ( path.startsWith( QLatin1String( "/vsitar/" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".tar" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".tar.gz" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".tgz" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsitar/" );
else if ( path.startsWith( QLatin1String( "/vsigzip/" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".gz" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsigzip/" );
else
return QString();
return QgsGdalUtils::vsiPrefixForPath( path );
}
uint qHash( const QVariant &variant )

View File

@ -708,6 +708,47 @@ QStringList QgsGdalUtils::multiLayerFileExtensions()
#endif
}
QString QgsGdalUtils::vsiPrefixForPath( const QString &path )
{
const QStringList vsiPrefixes = QgsGdalUtils::vsiArchivePrefixes();
for ( const QString &vsiPrefix : vsiPrefixes )
{
if ( path.startsWith( vsiPrefix, Qt::CaseInsensitive ) )
return vsiPrefix;
}
if ( path.endsWith( QLatin1String( ".shp.zip" ), Qt::CaseInsensitive ) )
{
// GDAL 3.1 Shapefile driver directly handles .shp.zip files
if ( GDALIdentifyDriverEx( path.toUtf8().constData(), GDAL_OF_VECTOR, nullptr, nullptr ) )
return QString();
return QStringLiteral( "/vsizip/" );
}
else if ( path.endsWith( QLatin1String( ".zip" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsizip/" );
else if ( path.endsWith( QLatin1String( ".tar" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".tar.gz" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".tgz" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsitar/" );
else if ( path.endsWith( QLatin1String( ".gz" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsigzip/" );
#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,7,0)
else if ( vsiPrefixes.contains( QStringLiteral( "/vsi7z/" ) ) &&
( path.endsWith( QLatin1String( ".7z" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".lpk" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".lpkx" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".mpk" ), Qt::CaseInsensitive ) ||
path.endsWith( QLatin1String( ".mpkx" ), Qt::CaseInsensitive ) ) )
return QStringLiteral( "/vsi7z/" );
else if ( vsiPrefixes.contains( QStringLiteral( "/vsirar/" ) ) &&
path.endsWith( QLatin1String( ".rar" ), Qt::CaseInsensitive ) )
return QStringLiteral( "/vsirar/" );
#endif
return QString();
}
bool QgsGdalUtils::vrtMatchesLayerType( const QString &vrtPath, Qgis::LayerType type )
{
CPLPushErrorHandler( CPLQuietErrorHandler );

View File

@ -220,6 +220,14 @@ class CORE_EXPORT QgsGdalUtils
*/
static QStringList multiLayerFileExtensions();
/**
* Returns a the vsi prefix which corresponds to a file \a path, or an empty
* string if the path is not associated with a vsi prefix.
*
* \since QGIS 3.32
*/
static QString vsiPrefixForPath( const QString &path );
/**
* Returns TRUE if the VRT file at the specified path is a VRT matching
* the given layer \a type.

View File

@ -18,6 +18,7 @@
#include "qgis.h"
#include "qgsapplication.h"
#include "qgsgdalutils.h"
#include <QDir>
#include <QFileInfo>
#include <QUrl>
@ -81,7 +82,7 @@ QString QgsPathResolver::readPath( const QString &f ) const
}
// if this is a VSIFILE, remove the VSI prefix and append to final result
QString vsiPrefix = qgsVsiPrefix( src );
QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( src );
if ( ! vsiPrefix.isEmpty() )
{
// unfortunately qgsVsiPrefix returns prefix also for files like "/x/y/z.gz"
@ -298,7 +299,7 @@ QString QgsPathResolver::writePath( const QString &s ) const
srcPath = srcFileInfo.canonicalFilePath();
// if this is a VSIFILE, remove the VSI prefix and append to final result
const QString vsiPrefix = qgsVsiPrefix( src );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( src );
if ( ! vsiPrefix.isEmpty() )
{
srcPath.remove( 0, vsiPrefix.size() );

View File

@ -22,6 +22,7 @@
#include "qgsproviderregistry.h"
#include "ogr/qgsogrhelperfunctions.h"
#include "qgsgdalutils.h"
#include <gdal.h>
#include <cpl_minixml.h>
@ -329,7 +330,7 @@ void QgsGdalSourceSelect::fillOpenOptions()
return;
const QString firstDataSource = mDataSources.at( 0 );
const QString vsiPrefix = qgsVsiPrefix( firstDataSource );
const QString vsiPrefix = QgsGdalUtils::vsiPrefixForPath( firstDataSource );
const QString scheme = QUrl( firstDataSource ).scheme();
const bool isRemoteNonVsiCurlUrl = vsiPrefix.isEmpty() && ( scheme.startsWith( QLatin1String( "http" ) ) || scheme == QLatin1String( "ftp" ) );
if ( isRemoteNonVsiCurlUrl )