Use separate provider metadata for each vector tile data provider

This commit is contained in:
Nyall Dawson 2023-03-20 13:13:09 +10:00
parent 2a6d6c0548
commit fa947eae22
10 changed files with 599 additions and 25 deletions

View File

@ -33,6 +33,11 @@
#include "providers/ogr/qgsogrprovider.h"
#include "providers/meshmemory/qgsmeshmemorydataprovider.h"
#include "qgsmbtilesvectortiledataprovider.h"
#include "qgsarcgisvectortileservicedataprovider.h"
#include "qgsxyzvectortiledataprovider.h"
#include "qgsvtpkvectortiledataprovider.h"
#ifdef HAVE_EPT
#include "providers/ept/qgseptprovider.h"
#endif
@ -187,9 +192,17 @@ void QgsProviderRegistry::init()
mProviders[ QgsOgrProvider::providerKey() ] = new QgsOgrProviderMetadata();
}
{
const QgsScopedRuntimeProfile profile( QObject::tr( "Create vector tile provider" ) );
const QgsScopedRuntimeProfile profile( QObject::tr( "Create vector tile providers" ) );
QgsProviderMetadata *vt = new QgsVectorTileProviderMetadata();
mProviders[ vt->key() ] = vt;
vt = new QgsXyzVectorTileDataProviderMetadata();
mProviders[ vt->key() ] = vt;
vt = new QgsVtpkVectorTileDataProviderMetadata();
mProviders[ vt->key() ] = vt;
vt = new QgsArcGisVectorTileServiceDataProviderMetadata();
mProviders[ vt->key() ] = vt;
vt = new QgsMbTilesVectorTileDataProviderMetadata();
mProviders[ vt->key() ] = vt;
}
#ifdef HAVE_EPT
{

View File

@ -15,9 +15,15 @@
#include "qgsarcgisvectortileservicedataprovider.h"
#include "qgsthreadingutils.h"
#include "qgsapplication.h"
#include <QIcon>
///@cond PRIVATE
QString QgsArcGisVectorTileServiceDataProvider::DATA_PROVIDER_KEY = QStringLiteral( "arcgisvectortileservice" );
QString QgsArcGisVectorTileServiceDataProvider::DATA_PROVIDER_DESCRIPTION = QObject::tr( "ArcGIS Vector Tile Service data provider" );
QgsArcGisVectorTileServiceDataProvider::QgsArcGisVectorTileServiceDataProvider( const QString &uri, const QString &sourcePath, const ProviderOptions &providerOptions, ReadFlags flags )
: QgsXyzVectorTileDataProvider( uri, providerOptions, flags )
, mSourcePath( sourcePath )
@ -29,14 +35,14 @@ QString QgsArcGisVectorTileServiceDataProvider::name() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QStringLiteral( "arcgisvectortileservice" );
return DATA_PROVIDER_KEY;
}
QString QgsArcGisVectorTileServiceDataProvider::description() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return tr( "ArcGIS Vector Tile Service" );
return DATA_PROVIDER_DESCRIPTION;
}
QgsVectorTileDataProvider *QgsArcGisVectorTileServiceDataProvider::clone() const
@ -62,6 +68,111 @@ bool QgsArcGisVectorTileServiceDataProvider::isValid() const
return true;
}
//
// QgsArcGisVectorTileServiceDataProviderMetadata
//
QgsArcGisVectorTileServiceDataProviderMetadata::QgsArcGisVectorTileServiceDataProviderMetadata()
: QgsProviderMetadata( QgsArcGisVectorTileServiceDataProvider::DATA_PROVIDER_KEY, QgsArcGisVectorTileServiceDataProvider::DATA_PROVIDER_DESCRIPTION )
{
}
QIcon QgsArcGisVectorTileServiceDataProviderMetadata::icon() const
{
return QgsApplication::getThemeIcon( QStringLiteral( "mIconVectorTileLayer.svg" ) );
}
QgsProviderMetadata::ProviderCapabilities QgsArcGisVectorTileServiceDataProviderMetadata::providerCapabilities() const
{
return QgsProviderMetadata::ProviderCapabilities();
}
QVariantMap QgsArcGisVectorTileServiceDataProviderMetadata::decodeUri( const QString &uri ) const
{
// TODO -- carefully thin out options which don't apply to arcgis vector tile services
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QVariantMap uriComponents;
uriComponents.insert( QStringLiteral( "type" ), dsUri.param( QStringLiteral( "type" ) ) );
if ( dsUri.hasParam( QStringLiteral( "serviceType" ) ) )
uriComponents.insert( QStringLiteral( "serviceType" ), dsUri.param( QStringLiteral( "serviceType" ) ) );
if ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "mbtiles" ) ||
( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "xyz" ) &&
!dsUri.param( QStringLiteral( "url" ) ).startsWith( QLatin1String( "http" ) ) ) )
{
uriComponents.insert( QStringLiteral( "path" ), dsUri.param( QStringLiteral( "url" ) ) );
}
else
{
uriComponents.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
}
if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
uriComponents.insert( QStringLiteral( "zmin" ), dsUri.param( QStringLiteral( "zmin" ) ) );
if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
uriComponents.insert( QStringLiteral( "zmax" ), dsUri.param( QStringLiteral( "zmax" ) ) );
dsUri.httpHeaders().updateMap( uriComponents );
if ( dsUri.hasParam( QStringLiteral( "styleUrl" ) ) )
uriComponents.insert( QStringLiteral( "styleUrl" ), dsUri.param( QStringLiteral( "styleUrl" ) ) );
const QString authcfg = dsUri.authConfigId();
if ( !authcfg.isEmpty() )
uriComponents.insert( QStringLiteral( "authcfg" ), authcfg );
return uriComponents;
}
QString QgsArcGisVectorTileServiceDataProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
// TODO -- carefully thin out options which don't apply to arcgis vector tile services
QgsDataSourceUri dsUri;
dsUri.setParam( QStringLiteral( "type" ), parts.value( QStringLiteral( "type" ) ).toString() );
if ( parts.contains( QStringLiteral( "serviceType" ) ) )
dsUri.setParam( QStringLiteral( "serviceType" ), parts[ QStringLiteral( "serviceType" ) ].toString() );
dsUri.setParam( QStringLiteral( "url" ), parts.value( parts.contains( QStringLiteral( "path" ) ) ? QStringLiteral( "path" ) : QStringLiteral( "url" ) ).toString() );
if ( parts.contains( QStringLiteral( "zmin" ) ) )
dsUri.setParam( QStringLiteral( "zmin" ), parts[ QStringLiteral( "zmin" ) ].toString() );
if ( parts.contains( QStringLiteral( "zmax" ) ) )
dsUri.setParam( QStringLiteral( "zmax" ), parts[ QStringLiteral( "zmax" ) ].toString() );
dsUri.httpHeaders().setFromMap( parts );
if ( parts.contains( QStringLiteral( "styleUrl" ) ) )
dsUri.setParam( QStringLiteral( "styleUrl" ), parts[ QStringLiteral( "styleUrl" ) ].toString() );
if ( parts.contains( QStringLiteral( "authcfg" ) ) )
dsUri.setAuthConfigId( parts[ QStringLiteral( "authcfg" ) ].toString() );
return dsUri.encodedUri();
}
QString QgsArcGisVectorTileServiceDataProviderMetadata::absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext & ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
return uri;
}
QString QgsArcGisVectorTileServiceDataProviderMetadata::relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext & ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
return uri;
}
QList<Qgis::LayerType> QgsArcGisVectorTileServiceDataProviderMetadata::supportedLayerTypes() const
{
return { Qgis::LayerType::VectorTile };
}
///@endcond

View File

@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsxyzvectortiledataprovider.h"
#include "qgsprovidermetadata.h"
#define SIP_NO_FILE
@ -34,15 +35,34 @@ class CORE_EXPORT QgsArcGisVectorTileServiceDataProvider : public QgsXyzVectorTi
const QgsDataProvider::ProviderOptions &providerOptions,
QgsDataProvider::ReadFlags flags );
QString name() const override;
QString description() const override;
QgsVectorTileDataProvider *clone() const override;
QString sourcePath() const override;
bool isValid() const override;
static QString DATA_PROVIDER_KEY;
static QString DATA_PROVIDER_DESCRIPTION;
private:
QString mSourcePath;
};
class QgsArcGisVectorTileServiceDataProviderMetadata : public QgsProviderMetadata
{
Q_OBJECT
public:
QgsArcGisVectorTileServiceDataProviderMetadata();
QIcon icon() const override;
ProviderCapabilities providerCapabilities() const override;
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
QString absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QString relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
};
///@endcond
#endif // QGSARCGISVECTORTILESERVICEDATAPROVIDER_H

View File

@ -20,9 +20,14 @@
#include "qgsvectortileloader.h"
#include "qgsziputils.h"
#include "qgslogger.h"
#include "qgsapplication.h"
#include <QIcon>
///@cond PRIVATE
QString QgsMbTilesVectorTileDataProvider::MB_TILES_VECTOR_TILE_DATA_PROVIDER_KEY = QStringLiteral( "mbtilesvectortiles" );
QString QgsMbTilesVectorTileDataProvider::MB_TILES_VECTOR_TILE_DATA_PROVIDER_DESCRIPTION = QObject::tr( "MBTile Vector Tiles data provider" );
QgsMbTilesVectorTileDataProvider::QgsMbTilesVectorTileDataProvider( const QString &uri, const ProviderOptions &providerOptions, ReadFlags flags )
: QgsVectorTileDataProvider( uri, providerOptions, flags )
{
@ -33,14 +38,14 @@ QString QgsMbTilesVectorTileDataProvider::name() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QStringLiteral( "mbtilesvectortiles" );
return MB_TILES_VECTOR_TILE_DATA_PROVIDER_KEY;
}
QString QgsMbTilesVectorTileDataProvider::description() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return tr( "MBTile Vector Tiles data provider" );
return MB_TILES_VECTOR_TILE_DATA_PROVIDER_DESCRIPTION;
}
QgsVectorTileDataProvider *QgsMbTilesVectorTileDataProvider::clone() const
@ -136,6 +141,126 @@ QByteArray QgsMbTilesVectorTileDataProvider::loadFromMBTiles( QgsMbTiles &mbTile
QgsDebugMsgLevel( QStringLiteral( "Tile blob size %1 -> uncompressed size %2" ).arg( gzippedTileData.size() ).arg( data.size() ), 2 );
return data;
}
//
// QgsMbTilesVectorTileDataProviderMetadata
//
QgsMbTilesVectorTileDataProviderMetadata::QgsMbTilesVectorTileDataProviderMetadata()
: QgsProviderMetadata( QgsMbTilesVectorTileDataProvider::MB_TILES_VECTOR_TILE_DATA_PROVIDER_KEY,
QgsMbTilesVectorTileDataProvider::MB_TILES_VECTOR_TILE_DATA_PROVIDER_DESCRIPTION )
{
}
QIcon QgsMbTilesVectorTileDataProviderMetadata::icon() const
{
return QgsApplication::getThemeIcon( QStringLiteral( "mIconVectorTileLayer.svg" ) );
}
QgsProviderMetadata::ProviderCapabilities QgsMbTilesVectorTileDataProviderMetadata::providerCapabilities() const
{
return FileBasedUris;
}
QVariantMap QgsMbTilesVectorTileDataProviderMetadata::decodeUri( const QString &uri ) const
{
// TODO -- carefully thin out options which don't apply to mbtiles
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QVariantMap uriComponents;
uriComponents.insert( QStringLiteral( "type" ), dsUri.param( QStringLiteral( "type" ) ) );
if ( dsUri.hasParam( QStringLiteral( "serviceType" ) ) )
uriComponents.insert( QStringLiteral( "serviceType" ), dsUri.param( QStringLiteral( "serviceType" ) ) );
if ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "mbtiles" ) ||
( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "xyz" ) &&
!dsUri.param( QStringLiteral( "url" ) ).startsWith( QLatin1String( "http" ) ) ) )
{
uriComponents.insert( QStringLiteral( "path" ), dsUri.param( QStringLiteral( "url" ) ) );
}
else
{
uriComponents.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
}
if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
uriComponents.insert( QStringLiteral( "zmin" ), dsUri.param( QStringLiteral( "zmin" ) ) );
if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
uriComponents.insert( QStringLiteral( "zmax" ), dsUri.param( QStringLiteral( "zmax" ) ) );
dsUri.httpHeaders().updateMap( uriComponents );
if ( dsUri.hasParam( QStringLiteral( "styleUrl" ) ) )
uriComponents.insert( QStringLiteral( "styleUrl" ), dsUri.param( QStringLiteral( "styleUrl" ) ) );
const QString authcfg = dsUri.authConfigId();
if ( !authcfg.isEmpty() )
uriComponents.insert( QStringLiteral( "authcfg" ), authcfg );
return uriComponents;
}
QString QgsMbTilesVectorTileDataProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
// TODO -- carefully thin out options which don't apply to mbtiles
QgsDataSourceUri dsUri;
dsUri.setParam( QStringLiteral( "type" ), parts.value( QStringLiteral( "type" ) ).toString() );
if ( parts.contains( QStringLiteral( "serviceType" ) ) )
dsUri.setParam( QStringLiteral( "serviceType" ), parts[ QStringLiteral( "serviceType" ) ].toString() );
dsUri.setParam( QStringLiteral( "url" ), parts.value( parts.contains( QStringLiteral( "path" ) ) ? QStringLiteral( "path" ) : QStringLiteral( "url" ) ).toString() );
if ( parts.contains( QStringLiteral( "zmin" ) ) )
dsUri.setParam( QStringLiteral( "zmin" ), parts[ QStringLiteral( "zmin" ) ].toString() );
if ( parts.contains( QStringLiteral( "zmax" ) ) )
dsUri.setParam( QStringLiteral( "zmax" ), parts[ QStringLiteral( "zmax" ) ].toString() );
dsUri.httpHeaders().setFromMap( parts );
if ( parts.contains( QStringLiteral( "styleUrl" ) ) )
dsUri.setParam( QStringLiteral( "styleUrl" ), parts[ QStringLiteral( "styleUrl" ) ].toString() );
if ( parts.contains( QStringLiteral( "authcfg" ) ) )
dsUri.setAuthConfigId( parts[ QStringLiteral( "authcfg" ) ].toString() );
return dsUri.encodedUri();
}
QString QgsMbTilesVectorTileDataProviderMetadata::absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
sourcePath = context.pathResolver().writePath( sourcePath );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), sourcePath );
return dsUri.encodedUri();
}
QString QgsMbTilesVectorTileDataProviderMetadata::relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
sourcePath = context.pathResolver().readPath( sourcePath );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), sourcePath );
return dsUri.encodedUri();
}
QList<Qgis::LayerType> QgsMbTilesVectorTileDataProviderMetadata::supportedLayerTypes() const
{
return { Qgis::LayerType::VectorTile };
}
///@endcond

View File

@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsvectortiledataprovider.h"
#include "qgsprovidermetadata.h"
class QgsMbTiles;
@ -44,6 +45,9 @@ class CORE_EXPORT QgsMbTilesVectorTileDataProvider : public QgsVectorTileDataPro
QByteArray readTile( const QgsTileMatrix &tileMatrix, const QgsTileXYZ &id, QgsFeedback *feedback = nullptr ) const override;
QList<QgsVectorTileRawData> readTiles( const QgsTileMatrix &, const QVector<QgsTileXYZ> &tiles, QgsFeedback *feedback = nullptr ) const override;
static QString MB_TILES_VECTOR_TILE_DATA_PROVIDER_KEY;
static QString MB_TILES_VECTOR_TILE_DATA_PROVIDER_DESCRIPTION;
private:
//! Returns raw tile data for a single tile loaded from MBTiles file
@ -51,6 +55,21 @@ class CORE_EXPORT QgsMbTilesVectorTileDataProvider : public QgsVectorTileDataPro
};
class QgsMbTilesVectorTileDataProviderMetadata : public QgsProviderMetadata
{
Q_OBJECT
public:
QgsMbTilesVectorTileDataProviderMetadata();
QIcon icon() const override;
ProviderCapabilities providerCapabilities() const override;
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
QString absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QString relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
};
///@endcond
#endif // QGSMBTILESVECTORTILEDATAPROVIDER_H

View File

@ -25,20 +25,6 @@ QgsVectorTileDataProvider::QgsVectorTileDataProvider(
: QgsDataProvider( uri, options, flags )
{}
QString QgsVectorTileDataProvider::name() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QStringLiteral( "vectortile" );
}
QString QgsVectorTileDataProvider::description() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QString();
}
QgsRectangle QgsVectorTileDataProvider::extent() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

View File

@ -17,9 +17,17 @@
#include "qgsthreadingutils.h"
#include "qgsvtpktiles.h"
#include "qgsvectortileloader.h"
#include "qgsapplication.h"
#include <QIcon>
///@cond PRIVATE
QString QgsVtpkVectorTileDataProvider::DATA_PROVIDER_KEY = QStringLiteral( "vtpkvectortiles" );
QString QgsVtpkVectorTileDataProvider::DATA_PROVIDER_DESCRIPTION = QObject::tr( "VTPK Vector Tiles data provider" );
QgsVtpkVectorTileDataProvider::QgsVtpkVectorTileDataProvider( const QString &uri, const ProviderOptions &providerOptions, ReadFlags flags )
: QgsVectorTileDataProvider( uri, providerOptions, flags )
{
@ -30,14 +38,14 @@ QString QgsVtpkVectorTileDataProvider::name() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QStringLiteral( "vtpkvectortiles" );
return DATA_PROVIDER_KEY;
}
QString QgsVtpkVectorTileDataProvider::description() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return tr( "VTPK Vector Tiles data provider" );
return DATA_PROVIDER_DESCRIPTION;
}
QgsVectorTileDataProvider *QgsVtpkVectorTileDataProvider::clone() const
@ -119,6 +127,124 @@ QByteArray QgsVtpkVectorTileDataProvider::loadFromVtpk( QgsVtpkTiles &vtpkTileRe
return tileData;
}
//
// QgsVtpkVectorTileDataProviderMetadata
//
QgsVtpkVectorTileDataProviderMetadata::QgsVtpkVectorTileDataProviderMetadata()
: QgsProviderMetadata( QgsVtpkVectorTileDataProvider::DATA_PROVIDER_KEY, QgsVtpkVectorTileDataProvider::DATA_PROVIDER_DESCRIPTION )
{
}
QIcon QgsVtpkVectorTileDataProviderMetadata::icon() const
{
return QgsApplication::getThemeIcon( QStringLiteral( "mIconVectorTileLayer.svg" ) );
}
QgsProviderMetadata::ProviderCapabilities QgsVtpkVectorTileDataProviderMetadata::providerCapabilities() const
{
return FileBasedUris;
}
QVariantMap QgsVtpkVectorTileDataProviderMetadata::decodeUri( const QString &uri ) const
{
// TODO -- carefully thin out options which don't apply to vtpk
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QVariantMap uriComponents;
uriComponents.insert( QStringLiteral( "type" ), dsUri.param( QStringLiteral( "type" ) ) );
if ( dsUri.hasParam( QStringLiteral( "serviceType" ) ) )
uriComponents.insert( QStringLiteral( "serviceType" ), dsUri.param( QStringLiteral( "serviceType" ) ) );
if ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "mbtiles" ) ||
( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "xyz" ) &&
!dsUri.param( QStringLiteral( "url" ) ).startsWith( QLatin1String( "http" ) ) ) )
{
uriComponents.insert( QStringLiteral( "path" ), dsUri.param( QStringLiteral( "url" ) ) );
}
else
{
uriComponents.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
}
if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
uriComponents.insert( QStringLiteral( "zmin" ), dsUri.param( QStringLiteral( "zmin" ) ) );
if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
uriComponents.insert( QStringLiteral( "zmax" ), dsUri.param( QStringLiteral( "zmax" ) ) );
dsUri.httpHeaders().updateMap( uriComponents );
if ( dsUri.hasParam( QStringLiteral( "styleUrl" ) ) )
uriComponents.insert( QStringLiteral( "styleUrl" ), dsUri.param( QStringLiteral( "styleUrl" ) ) );
const QString authcfg = dsUri.authConfigId();
if ( !authcfg.isEmpty() )
uriComponents.insert( QStringLiteral( "authcfg" ), authcfg );
return uriComponents;
}
QString QgsVtpkVectorTileDataProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
// TODO -- carefully thin out options which don't apply to vtpk
QgsDataSourceUri dsUri;
dsUri.setParam( QStringLiteral( "type" ), parts.value( QStringLiteral( "type" ) ).toString() );
if ( parts.contains( QStringLiteral( "serviceType" ) ) )
dsUri.setParam( QStringLiteral( "serviceType" ), parts[ QStringLiteral( "serviceType" ) ].toString() );
dsUri.setParam( QStringLiteral( "url" ), parts.value( parts.contains( QStringLiteral( "path" ) ) ? QStringLiteral( "path" ) : QStringLiteral( "url" ) ).toString() );
if ( parts.contains( QStringLiteral( "zmin" ) ) )
dsUri.setParam( QStringLiteral( "zmin" ), parts[ QStringLiteral( "zmin" ) ].toString() );
if ( parts.contains( QStringLiteral( "zmax" ) ) )
dsUri.setParam( QStringLiteral( "zmax" ), parts[ QStringLiteral( "zmax" ) ].toString() );
dsUri.httpHeaders().setFromMap( parts );
if ( parts.contains( QStringLiteral( "styleUrl" ) ) )
dsUri.setParam( QStringLiteral( "styleUrl" ), parts[ QStringLiteral( "styleUrl" ) ].toString() );
if ( parts.contains( QStringLiteral( "authcfg" ) ) )
dsUri.setAuthConfigId( parts[ QStringLiteral( "authcfg" ) ].toString() );
return dsUri.encodedUri();
}
QString QgsVtpkVectorTileDataProviderMetadata::absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
sourcePath = context.pathResolver().writePath( sourcePath );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), sourcePath );
return dsUri.encodedUri();
}
QString QgsVtpkVectorTileDataProviderMetadata::relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
sourcePath = context.pathResolver().readPath( sourcePath );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), sourcePath );
return dsUri.encodedUri();
}
QList<Qgis::LayerType> QgsVtpkVectorTileDataProviderMetadata::supportedLayerTypes() const
{
return { Qgis::LayerType::VectorTile };
}
///@endcond

View File

@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsvectortiledataprovider.h"
#include "qgsprovidermetadata.h"
#define SIP_NO_FILE
@ -36,6 +37,7 @@ class CORE_EXPORT QgsVtpkVectorTileDataProvider : public QgsVectorTileDataProvid
QgsDataProvider::ReadFlags flags );
QString name() const override;
QString description() const override;
QgsVectorTileDataProvider *clone() const override;
QString sourcePath() const override;
bool isValid() const override;
@ -43,6 +45,9 @@ class CORE_EXPORT QgsVtpkVectorTileDataProvider : public QgsVectorTileDataProvid
QByteArray readTile( const QgsTileMatrix &tileMatrix, const QgsTileXYZ &id, QgsFeedback *feedback = nullptr ) const override;
QList<QgsVectorTileRawData> readTiles( const QgsTileMatrix &, const QVector<QgsTileXYZ> &tiles, QgsFeedback *feedback = nullptr ) const override;
static QString DATA_PROVIDER_KEY;
static QString DATA_PROVIDER_DESCRIPTION;
private:
//! Returns raw tile data for a single tile loaded from VTPK file
@ -50,6 +55,22 @@ class CORE_EXPORT QgsVtpkVectorTileDataProvider : public QgsVectorTileDataProvid
};
class QgsVtpkVectorTileDataProviderMetadata : public QgsProviderMetadata
{
Q_OBJECT
public:
QgsVtpkVectorTileDataProviderMetadata();
QIcon icon() const override;
ProviderCapabilities providerCapabilities() const override;
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
QString absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QString relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
};
///@endcond
#endif // QGSVTPKVECTORTILEDATAPROVIDER_H

View File

@ -24,11 +24,14 @@
#include "qgsmessagelog.h"
#include "qgsblockingnetworkrequest.h"
#include "qgslogger.h"
#include <QIcon>
#include <QNetworkRequest>
///@cond PRIVATE
QString QgsXyzVectorTileDataProvider::DATA_PROVIDER_KEY = QStringLiteral( "xyzvectortiles" );
QString QgsXyzVectorTileDataProvider::DATA_PROVIDER_DESCRIPTION = QObject::tr( "XYZ Vector Tiles data provider" );
QgsXyzVectorTileDataProvider::QgsXyzVectorTileDataProvider( const QString &uri, const ProviderOptions &providerOptions, ReadFlags flags )
: QgsVectorTileDataProvider( uri, providerOptions, flags )
{
@ -43,15 +46,14 @@ QString QgsXyzVectorTileDataProvider::name() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return QStringLiteral( "xyzvectortiles" );
return DATA_PROVIDER_KEY;
}
QString QgsXyzVectorTileDataProvider::description() const
{
QGIS_PROTECT_QOBJECT_THREAD_ACCESS
return tr( "XYZ Vector Tiles data provider" );
return DATA_PROVIDER_DESCRIPTION;
}
QgsVectorTileDataProvider *QgsXyzVectorTileDataProvider::clone() const
@ -180,6 +182,136 @@ QByteArray QgsXyzVectorTileDataProvider::loadFromNetwork( const QgsTileXYZ &id,
return reply.content();
}
//
// QgsXyzVectorTileDataProviderMetadata
//
QgsXyzVectorTileDataProviderMetadata::QgsXyzVectorTileDataProviderMetadata()
: QgsProviderMetadata( QgsXyzVectorTileDataProvider::DATA_PROVIDER_KEY, QgsXyzVectorTileDataProvider::DATA_PROVIDER_DESCRIPTION )
{
}
QIcon QgsXyzVectorTileDataProviderMetadata::icon() const
{
return QgsApplication::getThemeIcon( QStringLiteral( "mIconVectorTileLayer.svg" ) );
}
QgsProviderMetadata::ProviderCapabilities QgsXyzVectorTileDataProviderMetadata::providerCapabilities() const
{
return FileBasedUris;
}
QVariantMap QgsXyzVectorTileDataProviderMetadata::decodeUri( const QString &uri ) const
{
// TODO -- carefully thin out options which don't apply to xyz vector tile services
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QVariantMap uriComponents;
uriComponents.insert( QStringLiteral( "type" ), dsUri.param( QStringLiteral( "type" ) ) );
if ( dsUri.hasParam( QStringLiteral( "serviceType" ) ) )
uriComponents.insert( QStringLiteral( "serviceType" ), dsUri.param( QStringLiteral( "serviceType" ) ) );
if ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "mbtiles" ) ||
( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "xyz" ) &&
!dsUri.param( QStringLiteral( "url" ) ).startsWith( QLatin1String( "http" ) ) ) )
{
uriComponents.insert( QStringLiteral( "path" ), dsUri.param( QStringLiteral( "url" ) ) );
}
else
{
uriComponents.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
}
if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
uriComponents.insert( QStringLiteral( "zmin" ), dsUri.param( QStringLiteral( "zmin" ) ) );
if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
uriComponents.insert( QStringLiteral( "zmax" ), dsUri.param( QStringLiteral( "zmax" ) ) );
dsUri.httpHeaders().updateMap( uriComponents );
if ( dsUri.hasParam( QStringLiteral( "styleUrl" ) ) )
uriComponents.insert( QStringLiteral( "styleUrl" ), dsUri.param( QStringLiteral( "styleUrl" ) ) );
const QString authcfg = dsUri.authConfigId();
if ( !authcfg.isEmpty() )
uriComponents.insert( QStringLiteral( "authcfg" ), authcfg );
return uriComponents;
}
QString QgsXyzVectorTileDataProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
// TODO -- carefully thin out options which don't apply to xyz vector tile services
QgsDataSourceUri dsUri;
dsUri.setParam( QStringLiteral( "type" ), parts.value( QStringLiteral( "type" ) ).toString() );
if ( parts.contains( QStringLiteral( "serviceType" ) ) )
dsUri.setParam( QStringLiteral( "serviceType" ), parts[ QStringLiteral( "serviceType" ) ].toString() );
dsUri.setParam( QStringLiteral( "url" ), parts.value( parts.contains( QStringLiteral( "path" ) ) ? QStringLiteral( "path" ) : QStringLiteral( "url" ) ).toString() );
if ( parts.contains( QStringLiteral( "zmin" ) ) )
dsUri.setParam( QStringLiteral( "zmin" ), parts[ QStringLiteral( "zmin" ) ].toString() );
if ( parts.contains( QStringLiteral( "zmax" ) ) )
dsUri.setParam( QStringLiteral( "zmax" ), parts[ QStringLiteral( "zmax" ) ].toString() );
dsUri.httpHeaders().setFromMap( parts );
if ( parts.contains( QStringLiteral( "styleUrl" ) ) )
dsUri.setParam( QStringLiteral( "styleUrl" ), parts[ QStringLiteral( "styleUrl" ) ].toString() );
if ( parts.contains( QStringLiteral( "authcfg" ) ) )
dsUri.setAuthConfigId( parts[ QStringLiteral( "authcfg" ) ].toString() );
return dsUri.encodedUri();
}
QString QgsXyzVectorTileDataProviderMetadata::absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
const QUrl sourceUrl( sourcePath );
if ( sourceUrl.isLocalFile() )
{
// relative path will become "file:./x.txt"
const QString relSrcUrl = context.pathResolver().writePath( sourceUrl.toLocalFile() );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( relSrcUrl ).toString() );
return dsUri.encodedUri();
}
return uri;
}
QString QgsXyzVectorTileDataProviderMetadata::relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const
{
QgsDataSourceUri dsUri;
dsUri.setEncodedUri( uri );
QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
const QUrl sourceUrl( sourcePath );
if ( sourceUrl.isLocalFile() ) // file-based URL? convert to relative path
{
const QString absSrcUrl = context.pathResolver().readPath( sourceUrl.toLocalFile() );
dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( absSrcUrl ).toString() );
return dsUri.encodedUri();
}
return uri;
}
QList<Qgis::LayerType> QgsXyzVectorTileDataProviderMetadata::supportedLayerTypes() const
{
return { Qgis::LayerType::VectorTile };
}
///@endcond

View File

@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsvectortiledataprovider.h"
#include "qgsprovidermetadata.h"
#define SIP_NO_FILE
@ -33,6 +34,7 @@ class CORE_EXPORT QgsXyzVectorTileDataProvider : public QgsVectorTileDataProvide
QgsDataProvider::ReadFlags flags );
QString name() const override;
QString description() const override;
QgsVectorTileDataProvider *clone() const override;
QString sourcePath() const override;
bool isValid() const override;
@ -42,6 +44,9 @@ class CORE_EXPORT QgsXyzVectorTileDataProvider : public QgsVectorTileDataProvide
QList<QgsVectorTileRawData> readTiles( const QgsTileMatrix &, const QVector<QgsTileXYZ> &tiles, QgsFeedback *feedback = nullptr ) const override;
QNetworkRequest tileRequest( const QgsTileMatrix &tileMatrix, const QgsTileXYZ &id, Qgis::RendererUsage usage ) const override;
static QString DATA_PROVIDER_KEY;
static QString DATA_PROVIDER_DESCRIPTION;
protected:
QString mAuthCfg;
@ -59,6 +64,22 @@ class CORE_EXPORT QgsXyzVectorTileDataProvider : public QgsVectorTileDataProvide
};
class QgsXyzVectorTileDataProviderMetadata : public QgsProviderMetadata
{
Q_OBJECT
public:
QgsXyzVectorTileDataProviderMetadata();
QIcon icon() const override;
ProviderCapabilities providerCapabilities() const override;
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
QString absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QString relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const override;
QList< Qgis::LayerType > supportedLayerTypes() const override;
};
///@endcond
#endif // QGSXYZVECTORTILEDATAPROVIDER_H