QGIS API Documentation 3.99.0-Master (752b475928d)
Loading...
Searching...
No Matches
qgsxyzvectortiledataprovider.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsxyzvectortiledataprovider.cpp
3 --------------------------------------
4 Date : March 2020
5 Copyright : (C) 2020 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsapplication.h"
19#include "qgsauthmanager.h"
21#include "qgslogger.h"
22#include "qgsmessagelog.h"
25#include "qgsthreadingutils.h"
26#include "qgstiles.h"
28#include "qgsvectortileloader.h"
29#include "qgsvectortileutils.h"
30
31#include <QIcon>
32#include <QNetworkRequest>
33
34#include "moc_qgsxyzvectortiledataprovider.cpp"
35
37
38QString QgsXyzVectorTileDataProvider::XYZ_DATA_PROVIDER_KEY = QStringLiteral( "xyzvectortiles" );
39QString QgsXyzVectorTileDataProvider::XYZ_DATA_PROVIDER_DESCRIPTION = QObject::tr( "XYZ Vector Tiles data provider" );
40
41//
42// QgsXyzVectorTileDataProviderBase
43//
44
45QgsXyzVectorTileDataProviderBase::QgsXyzVectorTileDataProviderBase( const QString &uri, const ProviderOptions &providerOptions, Qgis::DataProviderReadFlags flags )
46 : QgsVectorTileDataProvider( uri, providerOptions, flags )
47{
48 QgsDataSourceUri dsUri;
49 dsUri.setEncodedUri( uri );
50 mAuthCfg = dsUri.authConfigId();
51 mHeaders = dsUri.httpHeaders();
52}
53
54QgsXyzVectorTileDataProviderBase::QgsXyzVectorTileDataProviderBase( const QgsXyzVectorTileDataProviderBase &other )
56{
57 mAuthCfg = other.mAuthCfg;
58 mHeaders = other.mHeaders;
59}
60
61bool QgsXyzVectorTileDataProviderBase::supportsAsync() const
62{
63 return true;
64}
65
66QgsVectorTileRawData QgsXyzVectorTileDataProviderBase::readTile( const QgsTileMatrixSet &set, const QgsTileXYZ &id, QgsFeedback *feedback ) const
67{
68 return QgsVectorTileRawData( id, loadFromNetwork( id, set.tileMatrix( id.zoomLevel() ), sourcePath(), mAuthCfg, mHeaders, feedback ) );
69}
70
71QList<QgsVectorTileRawData> QgsXyzVectorTileDataProviderBase::readTiles( const QgsTileMatrixSet &set, const QVector<QgsTileXYZ> &tiles, QgsFeedback *feedback, Qgis::RendererUsage usage ) const
72{
73 QList<QgsVectorTileRawData> rawTiles;
74 rawTiles.reserve( tiles.size() );
75 for ( QgsTileXYZ id : std::as_const( tiles ) )
76 {
77 QMap<QString, QByteArray> data;
78 const QgsStringMap sources = sourcePaths();
79 QgsStringMap::const_iterator it = sources.constBegin();
80 for ( ; it != sources.constEnd(); ++it )
81 {
82 if ( feedback && feedback->isCanceled() )
83 break;
84
85 const QByteArray rawData = loadFromNetwork( id, set.tileMatrix( id.zoomLevel() ), it.value(), mAuthCfg, mHeaders, feedback, usage );
86 if ( !rawData.isEmpty() )
87 {
88 data[it.key()] = rawData;
89 }
90 }
91 rawTiles.append( QgsVectorTileRawData( id, data ) );
92 }
93 return rawTiles;
94}
95
96QList<QNetworkRequest> QgsXyzVectorTileDataProviderBase::tileRequests( const QgsTileMatrixSet &set, const QgsTileXYZ &id, Qgis::RendererUsage usage ) const
97{
98 QList<QNetworkRequest> requests;
99
100 const QgsStringMap sourcesPaths = sourcePaths();
101
102 QgsStringMap::const_iterator it = sourcesPaths.constBegin();
103
104 for ( ; it != sourcesPaths.constEnd(); ++it )
105 {
106 QString urlTemplate = it.value();
107 QString layerName = it.key();
108
109 if ( urlTemplate.contains( QLatin1String( "{usage}" ) ) )
110 {
111 switch ( usage )
112 {
114 urlTemplate.replace( QLatin1String( "{usage}" ), QLatin1String( "view" ) );
115 break;
117 urlTemplate.replace( QLatin1String( "{usage}" ), QLatin1String( "export" ) );
118 break;
120 urlTemplate.replace( QLatin1String( "{usage}" ), QString() );
121 break;
122 }
123 }
124
125 const QString url = QgsVectorTileUtils::formatXYZUrlTemplate( urlTemplate, id, set.tileMatrix( id.zoomLevel() ) );
126
127 QNetworkRequest request( url );
128 QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsXyzVectorTileDataProvider" ) );
129 QgsSetRequestInitiatorId( request, id.toString() );
130
131 request.setAttribute( static_cast<QNetworkRequest::Attribute>( QgsVectorTileDataProvider::DATA_COLUMN ), id.column() );
132 request.setAttribute( static_cast<QNetworkRequest::Attribute>( QgsVectorTileDataProvider::DATA_ROW ), id.row() );
133 request.setAttribute( static_cast<QNetworkRequest::Attribute>( QgsVectorTileDataProvider::DATA_ZOOM ), id.zoomLevel() );
134 request.setAttribute( static_cast<QNetworkRequest::Attribute>( QgsVectorTileDataProvider::DATA_SOURCE_ID ), layerName );
135
136 request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
137 request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true );
138
139 mHeaders.updateNetworkRequest( request );
140
141 if ( !mAuthCfg.isEmpty() && !QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg ) )
142 {
143 QgsMessageLog::logMessage( tr( "network request update failed for authentication config" ), tr( "Network" ) );
144 }
145
146 requests << request;
147 }
148
149 return requests;
150}
151
152QByteArray QgsXyzVectorTileDataProviderBase::loadFromNetwork( const QgsTileXYZ &id, const QgsTileMatrix &tileMatrix, const QString &requestUrl, const QString &authid, const QgsHttpHeaders &headers, QgsFeedback *feedback, Qgis::RendererUsage usage )
153{
154 QString url = QgsVectorTileUtils::formatXYZUrlTemplate( requestUrl, id, tileMatrix );
155
156 if ( url.contains( QLatin1String( "{usage}" ) ) )
157 {
158 switch ( usage )
159 {
161 url.replace( QLatin1String( "{usage}" ), QLatin1String( "view" ) );
162 break;
164 url.replace( QLatin1String( "{usage}" ), QLatin1String( "export" ) );
165 break;
167 url.replace( QLatin1String( "{usage}" ), QString() );
168 break;
169 }
170 }
171
172 QNetworkRequest nr;
173 nr.setUrl( QUrl( url ) );
174
175 headers.updateNetworkRequest( nr );
176
178 req.setAuthCfg( authid );
179 QgsDebugMsgLevel( QStringLiteral( "Blocking request: " ) + url, 2 );
180 QgsBlockingNetworkRequest::ErrorCode errCode = req.get( nr, false, feedback );
181 if ( errCode != QgsBlockingNetworkRequest::NoError )
182 {
183 QgsDebugError( QStringLiteral( "Request failed: " ) + url );
184 return QByteArray();
185 }
186 QgsNetworkReplyContent reply = req.reply();
187 QgsDebugMsgLevel( QStringLiteral( "Request successful, content size %1" ).arg( reply.content().size() ), 2 );
188 return reply.content();
189}
190
191
192//
193// QgsXyzVectorTileDataProviderMetadata
194//
195
196
197QgsXyzVectorTileDataProviderMetadata::QgsXyzVectorTileDataProviderMetadata()
198 : QgsProviderMetadata( QgsXyzVectorTileDataProvider::XYZ_DATA_PROVIDER_KEY, QgsXyzVectorTileDataProvider::XYZ_DATA_PROVIDER_DESCRIPTION )
199{
200}
201
202QgsXyzVectorTileDataProvider *QgsXyzVectorTileDataProviderMetadata::createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, Qgis::DataProviderReadFlags flags )
203{
204 return new QgsXyzVectorTileDataProvider( uri, options, flags );
205}
206
207QIcon QgsXyzVectorTileDataProviderMetadata::icon() const
208{
209 return QgsApplication::getThemeIcon( QStringLiteral( "mIconVectorTileLayer.svg" ) );
210}
211
212QgsProviderMetadata::ProviderCapabilities QgsXyzVectorTileDataProviderMetadata::providerCapabilities() const
213{
214 return FileBasedUris;
215}
216
217QVariantMap QgsXyzVectorTileDataProviderMetadata::decodeUri( const QString &uri ) const
218{
219 QgsDataSourceUri dsUri;
220 dsUri.setEncodedUri( uri );
221
222 QVariantMap uriComponents;
223 uriComponents.insert( QStringLiteral( "type" ), QStringLiteral( "xyz" ) );
224
225 if ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "mbtiles" ) ||
226 ( uriComponents[ QStringLiteral( "type" ) ] == QLatin1String( "xyz" ) &&
227 !dsUri.param( QStringLiteral( "url" ) ).startsWith( QLatin1String( "http" ) ) ) )
228 {
229 uriComponents.insert( QStringLiteral( "path" ), dsUri.param( QStringLiteral( "url" ) ) );
230 }
231 else
232 {
233 uriComponents.insert( QStringLiteral( "url" ), dsUri.param( QStringLiteral( "url" ) ) );
234 if ( dsUri.hasParam( QStringLiteral( "urlName" ) ) )
235 uriComponents.insert( QStringLiteral( "urlName" ), dsUri.param( QStringLiteral( "urlName" ) ) );
236 }
237 int i = 2;
238 while ( true )
239 {
240 QString url = dsUri.param( QStringLiteral( "url_%2" ).arg( i ) );
241 QString urlName = dsUri.param( QStringLiteral( "urlName_%2" ).arg( i ) );
242 if ( url.isEmpty() || urlName.isEmpty() )
243 break;
244 uriComponents.insert( QStringLiteral( "urlName_%2" ).arg( i ), urlName );
245 uriComponents.insert( QStringLiteral( "url_%2" ).arg( i ), url );
246 i++;
247 }
248
249
250 if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
251 uriComponents.insert( QStringLiteral( "zmin" ), dsUri.param( QStringLiteral( "zmin" ) ) );
252 if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
253 uriComponents.insert( QStringLiteral( "zmax" ), dsUri.param( QStringLiteral( "zmax" ) ) );
254
255 dsUri.httpHeaders().updateMap( uriComponents );
256
257 if ( dsUri.hasParam( QStringLiteral( "styleUrl" ) ) )
258 uriComponents.insert( QStringLiteral( "styleUrl" ), dsUri.param( QStringLiteral( "styleUrl" ) ) );
259
260 const QString authcfg = dsUri.authConfigId();
261 if ( !authcfg.isEmpty() )
262 uriComponents.insert( QStringLiteral( "authcfg" ), authcfg );
263
264 return uriComponents;
265}
266
267QString QgsXyzVectorTileDataProviderMetadata::encodeUri( const QVariantMap &parts ) const
268{
269 QgsDataSourceUri dsUri;
270 dsUri.setParam( QStringLiteral( "type" ), QStringLiteral( "xyz" ) );
271 dsUri.setParam( QStringLiteral( "url" ), parts.value( parts.contains( QStringLiteral( "path" ) ) ? QStringLiteral( "path" ) : QStringLiteral( "url" ) ).toString() );
272 if ( parts.contains( QStringLiteral( "urlName" ) ) )
273 dsUri.setParam( QStringLiteral( "urlName" ), parts[ QStringLiteral( "urlName" ) ].toString() );
274
275 int i = 2;
276 while ( true )
277 {
278 QString urlNameKey = QStringLiteral( "urlName_%2" ).arg( i );
279 QString urlKey = QStringLiteral( "url_%2" ).arg( i );
280
281 if ( !parts.contains( urlNameKey ) || !parts.contains( urlKey ) )
282 break;
283 QString url = dsUri.param( QStringLiteral( "url_%2" ).arg( i ) );
284 QString urlName = dsUri.param( QStringLiteral( "urlName_%2" ).arg( i ) );
285 if ( url.isEmpty() || urlName.isEmpty() )
286 break;
287
288 dsUri.setParam( urlNameKey, parts[ urlNameKey ].toString() );
289 dsUri.setParam( urlKey, parts[ urlKey ].toString() );
290 i++;
291 }
292
293 if ( parts.contains( QStringLiteral( "zmin" ) ) )
294 dsUri.setParam( QStringLiteral( "zmin" ), parts[ QStringLiteral( "zmin" ) ].toString() );
295 if ( parts.contains( QStringLiteral( "zmax" ) ) )
296 dsUri.setParam( QStringLiteral( "zmax" ), parts[ QStringLiteral( "zmax" ) ].toString() );
297
298 dsUri.httpHeaders().setFromMap( parts );
299
300 if ( parts.contains( QStringLiteral( "styleUrl" ) ) )
301 dsUri.setParam( QStringLiteral( "styleUrl" ), parts[ QStringLiteral( "styleUrl" ) ].toString() );
302
303 if ( parts.contains( QStringLiteral( "authcfg" ) ) )
304 dsUri.setAuthConfigId( parts[ QStringLiteral( "authcfg" ) ].toString() );
305
306 return dsUri.encodedUri();
307}
308
309QString QgsXyzVectorTileDataProviderMetadata::absoluteToRelativeUri( const QString &uri, const QgsReadWriteContext &context ) const
310{
311 QgsDataSourceUri dsUri;
312 dsUri.setEncodedUri( uri );
313
314 QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
315
316 const QUrl sourceUrl( sourcePath );
317 if ( sourceUrl.isLocalFile() )
318 {
319 // relative path will become "file:./x.txt"
320 const QString relSrcUrl = context.pathResolver().writePath( sourceUrl.toLocalFile() );
321 dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
322 dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( relSrcUrl ).toString( QUrl::DecodeReserved ) );
323 return dsUri.encodedUri();
324 }
325
326 return uri;
327}
328
329QString QgsXyzVectorTileDataProviderMetadata::relativeToAbsoluteUri( const QString &uri, const QgsReadWriteContext &context ) const
330{
331 QgsDataSourceUri dsUri;
332 dsUri.setEncodedUri( uri );
333
334 QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
335
336 const QUrl sourceUrl( sourcePath );
337 if ( sourceUrl.isLocalFile() ) // file-based URL? convert to relative path
338 {
339 const QString absSrcUrl = context.pathResolver().readPath( sourceUrl.toLocalFile() );
340 dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
341 dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( absSrcUrl ).toString( QUrl::DecodeReserved ) );
342 return dsUri.encodedUri();
343 }
344
345 return uri;
346}
347
348QList<Qgis::LayerType> QgsXyzVectorTileDataProviderMetadata::supportedLayerTypes() const
349{
351}
352
353
354//
355// QgsXyzVectorTileDataProvider
356//
357
358QgsXyzVectorTileDataProvider::QgsXyzVectorTileDataProvider( const QString &uri, const ProviderOptions &providerOptions, Qgis::DataProviderReadFlags flags )
359 : QgsXyzVectorTileDataProviderBase( uri, providerOptions, flags )
360{
361 QgsDataSourceUri dsUri;
362 dsUri.setEncodedUri( uri );
363
364 const QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
365 if ( !QgsVectorTileUtils::checkXYZUrlTemplate( sourcePath ) )
366 {
367 QgsDebugError( QStringLiteral( "Invalid format of URL for XYZ source: " ) + sourcePath );
368 mIsValid = false;
369 return;
370 }
371
372 int zMin = 0;
373 if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
374 zMin = dsUri.param( QStringLiteral( "zmin" ) ).toInt();
375
376 int zMax = 14;
377 if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
378 zMax = dsUri.param( QStringLiteral( "zmax" ) ).toInt();
379
380 mMatrixSet = QgsVectorTileMatrixSet::fromWebMercator( zMin, zMax );
381 mExtent = QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 );
382
383 mIsValid = true;
384}
385
386QgsXyzVectorTileDataProvider::QgsXyzVectorTileDataProvider( const QgsXyzVectorTileDataProvider &other )
387 : QgsXyzVectorTileDataProviderBase( other )
388{
389 mIsValid = other.mIsValid;
390 mExtent = other.mExtent;
391 mMatrixSet = other.mMatrixSet;
392}
393
394Qgis::DataProviderFlags QgsXyzVectorTileDataProvider::flags() const
395{
397}
398
399QString QgsXyzVectorTileDataProvider::name() const
400{
402
403 return XYZ_DATA_PROVIDER_KEY;
404}
405
406QString QgsXyzVectorTileDataProvider::description() const
407{
409
410 return XYZ_DATA_PROVIDER_DESCRIPTION;
411}
412
413QgsVectorTileDataProvider *QgsXyzVectorTileDataProvider::clone() const
414{
416
417 return new QgsXyzVectorTileDataProvider( *this );
418}
419
420bool QgsXyzVectorTileDataProvider::isValid() const
421{
423
424 return mIsValid;
425}
426
427QgsRectangle QgsXyzVectorTileDataProvider::extent() const
428{
430
431 return mExtent;
432}
433
434QgsCoordinateReferenceSystem QgsXyzVectorTileDataProvider::crs() const
435{
437
438 return QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) );
439}
440
441const QgsVectorTileMatrixSet &QgsXyzVectorTileDataProvider::tileMatrixSet() const
442{
444
445 return mMatrixSet;
446}
447
448QString QgsXyzVectorTileDataProvider::sourcePath() const
449{
451
452 QgsDataSourceUri dsUri;
453 dsUri.setEncodedUri( dataSourceUri() );
454 return dsUri.param( QStringLiteral( "url" ) );
455}
456
457QgsStringMap QgsXyzVectorTileDataProvider::sourcePaths() const
458{
460
461 QgsDataSourceUri dsUri;
462 dsUri.setEncodedUri( dataSourceUri() );
463
464 QgsStringMap paths = { { dsUri.param( QStringLiteral( "urlName" ) ), dsUri.param( QStringLiteral( "url" ) ) } };
465
466 int i = 2;
467 while ( true )
468 {
469 QString url = dsUri.param( QStringLiteral( "url_%2" ).arg( i ) );
470 QString urlName = dsUri.param( QStringLiteral( "urlName_%2" ).arg( i ) );
471 if ( url.isEmpty() || urlName.isEmpty() )
472 break;
473
474 paths.insert( urlName, url );
475 i++;
476 }
477
478 return paths;
479}
480
482
483
484
QFlags< DataProviderFlag > DataProviderFlags
Data provider flags.
Definition qgis.h:2315
@ FastExtent2D
Provider's 2D extent retrieval via QgsDataProvider::extent() is always guaranteed to be trivial/fast ...
Definition qgis.h:2310
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
Definition qgis.h:486
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
Definition qgis.h:195
RendererUsage
Usage of the renderer.
Definition qgis.h:3445
@ Export
Renderer used for printing or exporting to a file.
Definition qgis.h:3447
@ View
Renderer used for displaying on screen.
Definition qgis.h:3446
@ Unknown
Renderer used for unknown usage.
Definition qgis.h:3448
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
void setAuthCfg(const QString &authCfg)
Sets the authentication config id which should be used during the request.
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr, RequestFlags requestFlags=QgsBlockingNetworkRequest::RequestFlags())
Performs a "get" operation on the specified request.
@ NoError
No error was encountered.
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get(), post(), head() or put() request has been mad...
Represents a coordinate reference system (CRS).
Stores the component parts of a data source URI (e.g.
QByteArray encodedUri() const
Returns the complete encoded URI as a byte array.
bool hasParam(const QString &key) const
Returns true if a parameter with the specified key exists.
int removeParam(const QString &key)
Removes a generic parameter by key.
void setEncodedUri(const QByteArray &uri)
Sets the complete encoded uri.
void setAuthConfigId(const QString &authcfg)
Sets the authentication configuration ID for the URI.
QgsHttpHeaders httpHeaders() const
Returns http headers.
QString param(const QString &key) const
Returns a generic parameter value corresponding to the specified key.
void setParam(const QString &key, const QString &value)
Sets a generic parameter value on the URI.
QString authConfigId() const
Returns any associated authentication configuration ID stored in the URI.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
Implements simple HTTP header management.
bool updateMap(QVariantMap &map) const
Updates a map by adding all the HTTP headers.
bool updateNetworkRequest(QNetworkRequest &request) const
Updates a request by adding all the HTTP headers.
void setFromMap(const QVariantMap &map)
Loads headers from the map.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
QByteArray content() const
Returns the reply content.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Holds data provider key, description, and associated shared library file or function pointer informat...
QFlags< ProviderCapability > ProviderCapabilities
A container for the context for various read/write operations on objects.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
A rectangle specified with double values.
Defines a set of tile matrices for multiple zoom levels.
Definition qgstiles.h:274
QgsTileMatrix tileMatrix(int zoom) const
Returns the tile matrix corresponding to the specified zoom.
Definition qgstiles.cpp:156
Defines a matrix of tiles for a single zoom level: it is defined by its size (width *.
Definition qgstiles.h:158
Stores coordinates of a tile in a tile matrix set.
Definition qgstiles.h:39
Base class for vector tile layer data providers.
static int DATA_ZOOM
Role to set zoom attribute in the request so it can be retrieved later.
static int DATA_ROW
Role to set row attribute in the request so it can be retrieved later.
static int DATA_SOURCE_ID
Role to set source ID attribute in the request so it can be retrieved later.
static int DATA_COLUMN
Role to set column attribute in the request so it can be retrieved later.
Encapsulates properties of a vector tile matrix set, including tile origins and scaling information.
static QgsVectorTileMatrixSet fromWebMercator(int minimumZoom=0, int maximumZoom=14)
Returns a vector tile structure corresponding to the standard web mercator/GoogleCRS84Quad setup.
Keeps track of raw tile data from one or more sources that need to be decoded.
static bool checkXYZUrlTemplate(const QString &url)
Checks whether the URL template string is correct (contains {x}, {y} / {-y}, {z} placeholders).
static QString formatXYZUrlTemplate(const QString &url, QgsTileXYZ tile, const QgsTileMatrix &tileMatrix)
Returns formatted tile URL string replacing {x}, {y}, {z} placeholders (or {-y} instead of {y}...
QMap< QString, QString > QgsStringMap
Definition qgis.h:7132
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
#define QgsDebugError(str)
Definition qgslogger.h:57
#define QgsSetRequestInitiatorClass(request, _class)
#define QgsSetRequestInitiatorId(request, str)
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Setting options for creating vector data providers.