QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsvectortilelayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectortilelayer.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 
16 #include "qgsvectortilelayer.h"
17 
18 #include "qgslogger.h"
20 #include "qgsmbtiles.h"
21 #include "qgsvtpktiles.h"
24 #include "qgsvectortilelabeling.h"
25 #include "qgsvectortileloader.h"
26 #include "qgsvectortileutils.h"
28 
29 #include "qgsdatasourceuri.h"
33 #include "qgsjsonutils.h"
34 #include "qgspainting.h"
35 #include "qgsmaplayerfactory.h"
36 #include "qgsarcgisrestutils.h"
37 
38 #include <QUrl>
39 #include <QUrlQuery>
40 
41 QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseName, const LayerOptions &options )
43  , mTransformContext( options.transformContext )
44 {
46 
47  mDataSource = uri;
48 
49  setValid( loadDataSource() );
50 
51  // set a default renderer
55 }
56 
57 void QgsVectorTileLayer::setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &, const QgsDataProvider::ProviderOptions &, QgsDataProvider::ReadFlags )
58 {
59  mDataSource = dataSource;
60  mLayerName = baseName;
61  mDataProvider.reset();
62 
63  setValid( loadDataSource() );
64 }
65 
66 bool QgsVectorTileLayer::loadDataSource()
67 {
68  QgsDataSourceUri dsUri;
69  dsUri.setEncodedUri( mDataSource );
70 
71  setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) ) );
72 
73  mSourceType = dsUri.param( QStringLiteral( "type" ) );
74  mSourcePath = dsUri.param( QStringLiteral( "url" ) );
75  if ( mSourceType == QLatin1String( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
76  {
77  if ( !setupArcgisVectorTileServiceConnection( mSourcePath, dsUri ) )
78  return false;
79  }
80  else if ( mSourceType == QLatin1String( "xyz" ) )
81  {
82  if ( !QgsVectorTileUtils::checkXYZUrlTemplate( mSourcePath ) )
83  {
84  QgsDebugMsg( QStringLiteral( "Invalid format of URL for XYZ source: " ) + mSourcePath );
85  return false;
86  }
87 
88  // online tiles
89  int zMin = 0;
90  if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
91  zMin = dsUri.param( QStringLiteral( "zmin" ) ).toInt();
92 
93  int zMax = 14;
94  if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
95  zMax = dsUri.param( QStringLiteral( "zmax" ) ).toInt();
96 
97  mMatrixSet = QgsVectorTileMatrixSet::fromWebMercator( zMin, zMax );
98  setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) );
99  }
100  else if ( mSourceType == QLatin1String( "mbtiles" ) )
101  {
102  QgsMbTiles reader( mSourcePath );
103  if ( !reader.open() )
104  {
105  QgsDebugMsg( QStringLiteral( "failed to open MBTiles file: " ) + mSourcePath );
106  return false;
107  }
108 
109  const QString format = reader.metadataValue( QStringLiteral( "format" ) );
110  if ( format != QLatin1String( "pbf" ) )
111  {
112  QgsDebugMsg( QStringLiteral( "Cannot open MBTiles for vector tiles. Format = " ) + format );
113  return false;
114  }
115 
116  QgsDebugMsgLevel( QStringLiteral( "name: " ) + reader.metadataValue( QStringLiteral( "name" ) ), 2 );
117  bool minZoomOk, maxZoomOk;
118  const int minZoom = reader.metadataValue( QStringLiteral( "minzoom" ) ).toInt( &minZoomOk );
119  const int maxZoom = reader.metadataValue( QStringLiteral( "maxzoom" ) ).toInt( &maxZoomOk );
120  if ( minZoomOk )
121  mMatrixSet.dropMatricesOutsideZoomRange( minZoom, 99 );
122  if ( maxZoomOk )
123  mMatrixSet.dropMatricesOutsideZoomRange( 0, maxZoom );
124  QgsDebugMsgLevel( QStringLiteral( "zoom range: %1 - %2" ).arg( mMatrixSet.minimumZoom() ).arg( mMatrixSet.maximumZoom() ), 2 );
125 
126  QgsRectangle r = reader.extent();
127  QgsCoordinateTransform ct( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ),
128  QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) ), transformContext() );
129  ct.setBallparkTransformsAreAppropriate( true );
130  r = ct.transformBoundingBox( r );
131  setExtent( r );
132  }
133  else if ( mSourceType == QLatin1String( "vtpk" ) )
134  {
135  QgsVtpkTiles reader( mSourcePath );
136  if ( !reader.open() )
137  {
138  QgsDebugMsg( QStringLiteral( "failed to open VTPK file: " ) + mSourcePath );
139  return false;
140  }
141 
142  const QVariantMap metadata = reader.metadata();
143  const QString format = metadata.value( QStringLiteral( "tileInfo" ) ).toMap().value( QStringLiteral( "format" ) ).toString();
144  if ( format != QLatin1String( "pbf" ) )
145  {
146  QgsDebugMsg( QStringLiteral( "Cannot open VTPK for vector tiles. Format = " ) + format );
147  return false;
148  }
149 
150  mMatrixSet = reader.matrixSet();
151  setCrs( mMatrixSet.crs() );
152  setExtent( reader.extent( transformContext() ) );
153  }
154  else
155  {
156  QgsDebugMsg( QStringLiteral( "Unknown source type: " ) + mSourceType );
157  return false;
158  }
159 
160  const QgsDataProvider::ProviderOptions providerOptions { mTransformContext };
161  const QgsDataProvider::ReadFlags flags;
162  mDataProvider.reset( new QgsVectorTileDataProvider( providerOptions, flags ) );
163  mProviderKey = mDataProvider->name();
164 
165  return true;
166 }
167 
168 bool QgsVectorTileLayer::setupArcgisVectorTileServiceConnection( const QString &uri, const QgsDataSourceUri &dataSourceUri )
169 {
170  QString tileServiceUri = uri;
171  QUrl url( tileServiceUri );
172  // some services don't default to json format, while others do... so let's explicitly request it!
173  // (refs https://github.com/qgis/QGIS/issues/4231)
174  QUrlQuery query;
175  query.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "pjson" ) );
176  url.setQuery( query );
177 
178  QNetworkRequest request = QNetworkRequest( url );
179 
180  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) )
181 
182  QgsBlockingNetworkRequest networkRequest;
183  switch ( networkRequest.get( request ) )
184  {
186  break;
187 
191  return false;
192  }
193 
194  const QgsNetworkReplyContent content = networkRequest.reply();
195  const QByteArray raw = content.content();
196 
197  // Parse data
198  QJsonParseError err;
199  const QJsonDocument doc = QJsonDocument::fromJson( raw, &err );
200  if ( doc.isNull() )
201  {
202  return false;
203  }
204 
205  mArcgisLayerConfiguration = doc.object().toVariantMap();
206  if ( mArcgisLayerConfiguration.contains( QStringLiteral( "error" ) ) )
207  {
208  return false;
209  }
210 
211  if ( !mArcgisLayerConfiguration.value( QStringLiteral( "tiles" ) ).isValid() )
212  {
213  // maybe url is pointing to a resources/styles/root.json type url, that's ok too!
214  const QString sourceUri = mArcgisLayerConfiguration.value( QStringLiteral( "sources" ) ).toMap().value( QStringLiteral( "esri" ) ).toMap().value( QStringLiteral( "url" ) ).toString();
215  if ( !sourceUri.isEmpty() )
216  {
217  QUrl url( sourceUri );
218  // some services don't default to json format, while others do... so let's explicitly request it!
219  // (refs https://github.com/qgis/QGIS/issues/4231)
220  QUrlQuery query;
221  query.addQueryItem( QStringLiteral( "f" ), QStringLiteral( "pjson" ) );
222  url.setQuery( query );
223 
224  QNetworkRequest request = QNetworkRequest( url );
225 
226  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) )
227 
228  QgsBlockingNetworkRequest networkRequest;
229  switch ( networkRequest.get( request ) )
230  {
232  break;
233 
237  return false;
238  }
239 
240  const QgsNetworkReplyContent content = networkRequest.reply();
241  const QByteArray raw = content.content();
242 
243  // Parse data
244  QJsonParseError err;
245  const QJsonDocument doc = QJsonDocument::fromJson( raw, &err );
246  if ( doc.isNull() )
247  {
248  return false;
249  }
250 
251  tileServiceUri = sourceUri;
252 
253  // the resources/styles/root.json configuration is actually our style definition
254  mArcgisStyleConfiguration = mArcgisLayerConfiguration;
255  mArcgisLayerConfiguration = doc.object().toVariantMap();
256  if ( mArcgisLayerConfiguration.contains( QStringLiteral( "error" ) ) )
257  {
258  return false;
259  }
260  }
261  }
262 
263  mSourcePath = tileServiceUri + '/' + mArcgisLayerConfiguration.value( QStringLiteral( "tiles" ) ).toList().value( 0 ).toString();
264  if ( !QgsVectorTileUtils::checkXYZUrlTemplate( mSourcePath ) )
265  {
266  QgsDebugMsg( QStringLiteral( "Invalid format of URL for XYZ source: " ) + mSourcePath );
267  return false;
268  }
269 
270  mArcgisLayerConfiguration.insert( QStringLiteral( "serviceUri" ), tileServiceUri );
271 
272 
273  mMatrixSet.fromEsriJson( mArcgisLayerConfiguration );
274  setCrs( mMatrixSet.crs() );
275 
276  // if hardcoded zoom limits aren't specified, take them from the server
277  if ( dataSourceUri.hasParam( QStringLiteral( "zmin" ) ) )
278  mMatrixSet.dropMatricesOutsideZoomRange( dataSourceUri.param( QStringLiteral( "zmin" ) ).toInt(), 99 );
279 
280  if ( dataSourceUri.hasParam( QStringLiteral( "zmax" ) ) )
281  mMatrixSet.dropMatricesOutsideZoomRange( 0, dataSourceUri.param( QStringLiteral( "zmax" ) ).toInt() );
282 
283  const QVariantMap fullExtent = mArcgisLayerConfiguration.value( QStringLiteral( "fullExtent" ) ).toMap();
284  if ( !fullExtent.isEmpty() )
285  {
286  const QgsRectangle fullExtentRect(
287  fullExtent.value( QStringLiteral( "xmin" ) ).toDouble(),
288  fullExtent.value( QStringLiteral( "ymin" ) ).toDouble(),
289  fullExtent.value( QStringLiteral( "xmax" ) ).toDouble(),
290  fullExtent.value( QStringLiteral( "ymax" ) ).toDouble()
291  );
292 
293  const QgsCoordinateReferenceSystem fullExtentCrs = QgsArcGisRestUtils::convertSpatialReference( fullExtent.value( QStringLiteral( "spatialReference" ) ).toMap() );
294  const QgsCoordinateTransform extentTransform( fullExtentCrs, crs(), transformContext() );
295  try
296  {
297  setExtent( extentTransform.transformBoundingBox( fullExtentRect ) );
298  }
299  catch ( QgsCsException & )
300  {
301  QgsDebugMsg( QStringLiteral( "Could not transform layer fullExtent to layer CRS" ) );
302  }
303  }
304  else
305  {
306  // if no fullExtent specified in JSON, default to web mercator specs full extent
307  const QgsCoordinateTransform extentTransform( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) ), crs(), transformContext() );
308  try
309  {
310  setExtent( extentTransform.transformBoundingBox( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) ) );
311  }
312  catch ( QgsCsException & )
313  {
314  QgsDebugMsg( QStringLiteral( "Could not transform layer extent to layer CRS" ) );
315  }
316  }
317 
318  return true;
319 }
320 
322 
323 
325 {
326  const QgsVectorTileLayer::LayerOptions options( mTransformContext );
327  QgsVectorTileLayer *layer = new QgsVectorTileLayer( source(), name(), options );
328  layer->setRenderer( renderer() ? renderer()->clone() : nullptr );
329  return layer;
330 }
331 
333 {
334  return mDataProvider.get();
335 }
336 
338 {
339  return mDataProvider.get();
340 }
341 
343 {
344  return new QgsVectorTileLayerRenderer( this, rendererContext );
345 }
346 
347 bool QgsVectorTileLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext &context )
348 {
349  setValid( loadDataSource() );
350 
351  const QDomElement matrixSetElement = layerNode.firstChildElement( QStringLiteral( "matrixSet" ) );
352  if ( !matrixSetElement.isNull() )
353  {
354  mMatrixSet.readXml( matrixSetElement, context );
355  setCrs( mMatrixSet.crs() );
356  }
357 
358  QString errorMsg;
359  if ( !readSymbology( layerNode, errorMsg, context ) )
360  return false;
361 
362  readStyleManager( layerNode );
363  return true;
364 }
365 
366 bool QgsVectorTileLayer::writeXml( QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context ) const
367 {
368  QDomElement mapLayerNode = layerNode.toElement();
369  mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::VectorTileLayer ) );
370 
371  mapLayerNode.appendChild( mMatrixSet.writeXml( doc, context ) );
372 
373  // add provider node
374  if ( mDataProvider )
375  {
376  QDomElement provider = doc.createElement( QStringLiteral( "provider" ) );
377  const QDomText providerText = doc.createTextNode( providerType() );
378  provider.appendChild( providerText );
379  mapLayerNode.appendChild( provider );
380  }
381 
382  writeStyleManager( layerNode, doc );
383 
384  QString errorMsg;
385  return writeSymbology( layerNode, doc, errorMsg, context );
386 }
387 
388 bool QgsVectorTileLayer::readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories )
389 {
390  const QDomElement elem = node.toElement();
391 
392  readCommonStyle( elem, context, categories );
393 
394  const QDomElement elemRenderer = elem.firstChildElement( QStringLiteral( "renderer" ) );
395  if ( elemRenderer.isNull() )
396  {
397  errorMessage = tr( "Missing <renderer> tag" );
398  return false;
399  }
400  const QString rendererType = elemRenderer.attribute( QStringLiteral( "type" ) );
401 
402  if ( categories.testFlag( Symbology ) )
403  {
404  QgsVectorTileRenderer *r = nullptr;
405  if ( rendererType == QLatin1String( "basic" ) )
407  else
408  {
409  errorMessage = tr( "Unknown renderer type: " ) + rendererType;
410  return false;
411  }
412 
413  r->readXml( elemRenderer, context );
414  setRenderer( r );
415  }
416 
417  if ( categories.testFlag( Labeling ) )
418  {
419  setLabeling( nullptr );
420  const QDomElement elemLabeling = elem.firstChildElement( QStringLiteral( "labeling" ) );
421  if ( !elemLabeling.isNull() )
422  {
423  const QString labelingType = elemLabeling.attribute( QStringLiteral( "type" ) );
424  QgsVectorTileLabeling *labeling = nullptr;
425  if ( labelingType == QLatin1String( "basic" ) )
427  else
428  {
429  errorMessage = tr( "Unknown labeling type: " ) + rendererType;
430  }
431 
432  if ( labeling )
433  {
434  labeling->readXml( elemLabeling, context );
436  }
437  }
438  }
439 
440  if ( categories.testFlag( Symbology ) )
441  {
442  // get and set the blend mode if it exists
443  const QDomNode blendModeNode = node.namedItem( QStringLiteral( "blendMode" ) );
444  if ( !blendModeNode.isNull() )
445  {
446  const QDomElement e = blendModeNode.toElement();
447  setBlendMode( QgsPainting::getCompositionMode( static_cast< QgsPainting::BlendMode >( e.text().toInt() ) ) );
448  }
449  }
450 
451  // get and set the layer transparency
452  if ( categories.testFlag( Rendering ) )
453  {
454  const QDomNode layerOpacityNode = node.namedItem( QStringLiteral( "layerOpacity" ) );
455  if ( !layerOpacityNode.isNull() )
456  {
457  const QDomElement e = layerOpacityNode.toElement();
458  setOpacity( e.text().toDouble() );
459  }
460  }
461 
462  return true;
463 }
464 
465 bool QgsVectorTileLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const
466 {
467  Q_UNUSED( errorMessage )
468  QDomElement elem = node.toElement();
469 
470  writeCommonStyle( elem, doc, context, categories );
471 
472  if ( mRenderer )
473  {
474  QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) );
475  elemRenderer.setAttribute( QStringLiteral( "type" ), mRenderer->type() );
476  if ( categories.testFlag( Symbology ) )
477  {
478  mRenderer->writeXml( elemRenderer, context );
479  }
480  elem.appendChild( elemRenderer );
481  }
482 
483  if ( mLabeling && categories.testFlag( Labeling ) )
484  {
485  QDomElement elemLabeling = doc.createElement( QStringLiteral( "labeling" ) );
486  elemLabeling.setAttribute( QStringLiteral( "type" ), mLabeling->type() );
487  mLabeling->writeXml( elemLabeling, context );
488  elem.appendChild( elemLabeling );
489  }
490 
491  if ( categories.testFlag( Symbology ) )
492  {
493  // add the blend mode field
494  QDomElement blendModeElem = doc.createElement( QStringLiteral( "blendMode" ) );
495  const QDomText blendModeText = doc.createTextNode( QString::number( QgsPainting::getBlendModeEnum( blendMode() ) ) );
496  blendModeElem.appendChild( blendModeText );
497  node.appendChild( blendModeElem );
498  }
499 
500  // add the layer opacity
501  if ( categories.testFlag( Rendering ) )
502  {
503  QDomElement layerOpacityElem = doc.createElement( QStringLiteral( "layerOpacity" ) );
504  const QDomText layerOpacityText = doc.createTextNode( QString::number( opacity() ) );
505  layerOpacityElem.appendChild( layerOpacityText );
506  node.appendChild( layerOpacityElem );
507  }
508 
509  return true;
510 }
511 
513 {
514  if ( mDataProvider )
515  mDataProvider->setTransformContext( transformContext );
516 
517  mTransformContext = transformContext;
519 }
520 
521 QString QgsVectorTileLayer::loadDefaultStyle( bool &resultFlag )
522 {
523  QString error;
524  QStringList warnings;
525  resultFlag = loadDefaultStyle( error, warnings );
526  return error;
527 }
528 
529 Qgis::MapLayerProperties QgsVectorTileLayer::properties() const
530 {
531  Qgis::MapLayerProperties res;
532  if ( mSourceType == QLatin1String( "xyz" ) )
533  {
534  // always consider xyz vector tiles as basemap layers
536  }
537  else
538  {
539  // TODO when should we consider mbtiles layers as basemap layers? potentially if their extent is "large"?
540  }
541 
542  return res;
543 }
544 
545 bool QgsVectorTileLayer::loadDefaultStyle( QString &error, QStringList &warnings )
546 {
547  QgsDataSourceUri dsUri;
548  dsUri.setEncodedUri( mDataSource );
549 
550  QVariantMap styleDefinition;
552  QString styleUrl;
553  if ( !dsUri.param( QStringLiteral( "styleUrl" ) ).isEmpty() )
554  {
555  styleUrl = dsUri.param( QStringLiteral( "styleUrl" ) );
556  }
557  else if ( mSourceType == QLatin1String( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
558  {
559  // for ArcMap VectorTileServices we default to the defaultStyles URL from the layer configuration
560  styleUrl = mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString()
561  + '/' + mArcgisLayerConfiguration.value( QStringLiteral( "defaultStyles" ) ).toString();
562  }
563 
564  if ( mSourceType == QLatin1String( "vtpk" ) )
565  {
566  QgsVtpkTiles reader( mSourcePath );
567  if ( !reader.open() )
568  {
569  QgsDebugMsg( QStringLiteral( "failed to open VTPK file: " ) + mSourcePath );
570  return false;
571  }
572 
573  styleDefinition = reader.styleDefinition();
574 
575  const QVariantMap spriteDefinition = reader.spriteDefinition();
576  if ( !spriteDefinition.isEmpty() )
577  {
578  const QImage spriteImage = reader.spriteImage();
579  context.setSprites( spriteImage, spriteDefinition );
580  }
581  }
582  else if ( !mArcgisStyleConfiguration.isEmpty() || !styleUrl.isEmpty() )
583  {
584  if ( !mArcgisStyleConfiguration.isEmpty() )
585  {
586  styleDefinition = mArcgisStyleConfiguration;
587  }
588  else
589  {
590  QNetworkRequest request = QNetworkRequest( QUrl( styleUrl ) );
591 
592  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) );
593 
594  QgsBlockingNetworkRequest networkRequest;
595  switch ( networkRequest.get( request ) )
596  {
598  break;
599 
603  error = QObject::tr( "Error retrieving default style" );
604  return false;
605  }
606 
607  const QgsNetworkReplyContent content = networkRequest.reply();
608  styleDefinition = QgsJsonUtils::parseJson( content.content() ).toMap();
609  }
610 
611  if ( styleDefinition.contains( QStringLiteral( "sprite" ) ) )
612  {
613  // retrieve sprite definition
614  QString spriteUriBase;
615  if ( styleDefinition.value( QStringLiteral( "sprite" ) ).toString().startsWith( QLatin1String( "http" ) ) )
616  {
617  spriteUriBase = styleDefinition.value( QStringLiteral( "sprite" ) ).toString();
618  }
619  else
620  {
621  spriteUriBase = styleUrl + '/' + styleDefinition.value( QStringLiteral( "sprite" ) ).toString();
622  }
623 
624  for ( int resolution = 2; resolution > 0; resolution-- )
625  {
626  QUrl spriteUrl = QUrl( spriteUriBase );
627  spriteUrl.setPath( spriteUrl.path() + QStringLiteral( "%1.json" ).arg( resolution > 1 ? QStringLiteral( "@%1x" ).arg( resolution ) : QString() ) );
628  QNetworkRequest request = QNetworkRequest( spriteUrl );
629  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) )
630  QgsBlockingNetworkRequest networkRequest;
631  switch ( networkRequest.get( request ) )
632  {
634  {
635  const QgsNetworkReplyContent content = networkRequest.reply();
636  const QVariantMap spriteDefinition = QgsJsonUtils::parseJson( content.content() ).toMap();
637 
638  // retrieve sprite images
639  QUrl spriteUrl = QUrl( spriteUriBase );
640  spriteUrl.setPath( spriteUrl.path() + QStringLiteral( "%1.png" ).arg( resolution > 1 ? QStringLiteral( "@%1x" ).arg( resolution ) : QString() ) );
641  QNetworkRequest request = QNetworkRequest( spriteUrl );
642  QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsVectorTileLayer" ) )
643  QgsBlockingNetworkRequest networkRequest;
644  switch ( networkRequest.get( request ) )
645  {
647  {
648  const QgsNetworkReplyContent imageContent = networkRequest.reply();
649  const QImage spriteImage( QImage::fromData( imageContent.content() ) );
650  context.setSprites( spriteImage, spriteDefinition );
651  break;
652  }
653 
657  break;
658  }
659 
660  break;
661  }
662 
666  break;
667  }
668 
669  if ( !context.spriteDefinitions().isEmpty() )
670  break;
671  }
672  }
673  }
674 
675  if ( !styleDefinition.isEmpty() )
676  {
677  // convert automatically from pixel sizes to millimeters, because pixel sizes
678  // are a VERY edge case in QGIS and don't play nice with hidpi map renders or print layouts
680  //assume source uses 96 dpi
681  context.setPixelSizeConversionFactor( 25.4 / 96.0 );
682 
683  QgsMapBoxGlStyleConverter converter;
684  if ( converter.convert( styleDefinition, &context ) != QgsMapBoxGlStyleConverter::Success )
685  {
686  warnings = converter.warnings();
687  error = converter.errorMessage();
688  return false;
689  }
690 
691  setRenderer( converter.renderer() );
692  setLabeling( converter.labeling() );
693  warnings = converter.warnings();
694  return true;
695  }
696  else
697  {
698  bool resultFlag = false;
699  error = QgsMapLayer::loadDefaultStyle( resultFlag );
700  return resultFlag;
701  }
702 }
703 
704 QString QgsVectorTileLayer::loadDefaultMetadata( bool &resultFlag )
705 {
706  QgsDataSourceUri dsUri;
707  dsUri.setEncodedUri( mDataSource );
708  if ( mSourceType == QLatin1String( "xyz" ) && dsUri.param( QStringLiteral( "serviceType" ) ) == QLatin1String( "arcgis" ) )
709  {
710  // populate default metadata
712  metadata.setIdentifier( mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() );
713  const QString parentIdentifier = mArcgisLayerConfiguration.value( QStringLiteral( "serviceItemId" ) ).toString();
714  if ( !parentIdentifier.isEmpty() )
715  {
716  metadata.setParentIdentifier( parentIdentifier );
717  }
718  metadata.setType( QStringLiteral( "dataset" ) );
719  metadata.setTitle( mArcgisLayerConfiguration.value( QStringLiteral( "name" ) ).toString() );
720  const QString copyright = mArcgisLayerConfiguration.value( QStringLiteral( "copyrightText" ) ).toString();
721  if ( !copyright.isEmpty() )
722  metadata.setRights( QStringList() << copyright );
723  metadata.addLink( QgsAbstractMetadataBase::Link( tr( "Source" ), QStringLiteral( "WWW:LINK" ), mArcgisLayerConfiguration.value( QStringLiteral( "serviceUri" ) ).toString() ) );
724 
726 
727  resultFlag = true;
728  return QString();
729  }
730  else if ( mSourceType == QLatin1String( "vtpk" ) )
731  {
732  QgsVtpkTiles reader( mSourcePath );
733  if ( !reader.open() )
734  {
735  QgsDebugMsg( QStringLiteral( "failed to open VTPK file: " ) + mSourcePath );
736  resultFlag = false;
737  }
738  else
739  {
740  setMetadata( reader.layerMetadata() );
741  resultFlag = true;
742  }
743  return QString();
744  }
745  else
746  {
747  QgsMapLayer::loadDefaultMetadata( resultFlag );
748  resultFlag = true;
749  return QString();
750  }
751 }
752 
753 QString QgsVectorTileLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const
754 {
755  QgsDataSourceUri dsUri;
756  dsUri.setEncodedUri( source );
757 
758  const QString sourceType = dsUri.param( QStringLiteral( "type" ) );
759  QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
760  if ( sourceType == QLatin1String( "xyz" ) )
761  {
762  const QUrl sourceUrl( sourcePath );
763  if ( sourceUrl.isLocalFile() )
764  {
765  // relative path will become "file:./x.txt"
766  const QString relSrcUrl = context.pathResolver().writePath( sourceUrl.toLocalFile() );
767  dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
768  dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( relSrcUrl ).toString() );
769  return dsUri.encodedUri();
770  }
771  }
772  else if ( sourceType == QLatin1String( "mbtiles" ) )
773  {
775  dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
776  dsUri.setParam( QStringLiteral( "url" ), sourcePath );
777  return dsUri.encodedUri();
778  }
779 
780  return source;
781 }
782 
783 QString QgsVectorTileLayer::decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const
784 {
785  Q_UNUSED( provider )
786 
787  QgsDataSourceUri dsUri;
788  dsUri.setEncodedUri( source );
789 
790  const QString sourceType = dsUri.param( QStringLiteral( "type" ) );
791  QString sourcePath = dsUri.param( QStringLiteral( "url" ) );
792  if ( sourceType == QLatin1String( "xyz" ) )
793  {
794  const QUrl sourceUrl( sourcePath );
795  if ( sourceUrl.isLocalFile() ) // file-based URL? convert to relative path
796  {
797  const QString absSrcUrl = context.pathResolver().readPath( sourceUrl.toLocalFile() );
798  dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
799  dsUri.setParam( QStringLiteral( "url" ), QUrl::fromLocalFile( absSrcUrl ).toString() );
800  return dsUri.encodedUri();
801  }
802  }
803  else if ( sourceType == QLatin1String( "mbtiles" ) )
804  {
806  dsUri.removeParam( QStringLiteral( "url" ) ); // needed because setParam() would insert second "url" key
807  dsUri.setParam( QStringLiteral( "url" ), sourcePath );
808  return dsUri.encodedUri();
809  }
810 
811  return source;
812 }
813 
815 {
816  const QgsLayerMetadataFormatter htmlFormatter( metadata() );
817 
818  QString info = QStringLiteral( "<html><head></head>\n<body>\n" );
819 
820  info += generalHtmlMetadata();
821 
822  info += QStringLiteral( "<h1>" ) + tr( "Information from provider" ) + QStringLiteral( "</h1>\n<hr>\n" ) %
823  QStringLiteral( "<table class=\"list-view\">\n" );
824 
825  info += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Source type" ) % QStringLiteral( "</td><td>" ) % sourceType() % QStringLiteral( "</td></tr>\n" );
826 
827  info += QStringLiteral( "<tr><td class=\"highlight\">" ) % tr( "Zoom levels" ) % QStringLiteral( "</td><td>" ) % QStringLiteral( "%1 - %2" ).arg( sourceMinZoom() ).arg( sourceMaxZoom() ) % QStringLiteral( "</td></tr>\n" );
828 
829  info += QLatin1String( "</table>\n<br>" );
830 
831  // CRS
832  info += crsHtmlMetadata();
833 
834  // Identification section
835  info += QStringLiteral( "<h1>" ) % tr( "Identification" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
836  htmlFormatter.identificationSectionHtml() %
837  QStringLiteral( "<br>\n" ) %
838 
839  // extent section
840  QStringLiteral( "<h1>" ) % tr( "Extent" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
841  htmlFormatter.extentSectionHtml( ) %
842  QStringLiteral( "<br>\n" ) %
843 
844  // Start the Access section
845  QStringLiteral( "<h1>" ) % tr( "Access" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
846  htmlFormatter.accessSectionHtml( ) %
847  QStringLiteral( "<br>\n" ) %
848 
849 
850  // Start the contacts section
851  QStringLiteral( "<h1>" ) % tr( "Contacts" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
852  htmlFormatter.contactsSectionHtml( ) %
853  QStringLiteral( "<br><br>\n" ) %
854 
855  // Start the links section
856  QStringLiteral( "<h1>" ) % tr( "References" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
857  htmlFormatter.linksSectionHtml( ) %
858  QStringLiteral( "<br>\n" ) %
859 
860  // Start the history section
861  QStringLiteral( "<h1>" ) % tr( "History" ) % QStringLiteral( "</h1>\n<hr>\n" ) %
862  htmlFormatter.historySectionHtml( ) %
863  QStringLiteral( "<br>\n" ) %
864 
865  QStringLiteral( "\n</body>\n</html>\n" );
866 
867  return info;
868 }
869 
871 {
872  const QgsTileMatrix tileMatrix = mMatrixSet.tileMatrix( tileID.zoomLevel() );
873  const QgsTileRange tileRange( tileID.column(), tileID.column(), tileID.row(), tileID.row() );
874 
875  QgsDataSourceUri dsUri;
876  dsUri.setEncodedUri( mDataSource );
877  const QString authcfg = dsUri.authConfigId();
878 
879  QList<QgsVectorTileRawData> rawTiles = QgsVectorTileLoader::blockingFetchTileRawData( mSourceType, mSourcePath, tileMatrix, QPointF(), tileRange, authcfg, dsUri.httpHeaders() );
880  if ( rawTiles.isEmpty() )
881  return QByteArray();
882  return rawTiles.first().data;
883 }
884 
886 {
887  mRenderer.reset( r );
888  triggerRepaint();
889 }
890 
892 {
893  return mRenderer.get();
894 }
895 
897 {
898  mLabeling.reset( labeling );
899  triggerRepaint();
900 }
901 
903 {
904  return mLabeling.get();
905 }
906 
907 
908 
909 //
910 // QgsVectorTileDataProvider
911 //
913 QgsVectorTileDataProvider::QgsVectorTileDataProvider(
914  const ProviderOptions &options,
915  QgsDataProvider::ReadFlags flags )
916  : QgsDataProvider( QString(), options, flags )
917 {}
918 
920 {
921  return QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) );
922 }
923 
924 QString QgsVectorTileDataProvider::name() const
925 {
926  return QStringLiteral( "vectortile" );
927 }
928 
929 QString QgsVectorTileDataProvider::description() const
930 {
931  return QString();
932 }
933 
934 QgsRectangle QgsVectorTileDataProvider::extent() const
935 {
936  return QgsRectangle();
937 }
938 
939 bool QgsVectorTileDataProvider::isValid() const
940 {
941  return true;
942 }
943 
944 bool QgsVectorTileDataProvider::renderInPreview( const PreviewContext &context )
945 {
946  // Vector tiles by design are very CPU light to render, so we are much more permissive here compared
947  // with other layer types. (Generally if a vector tile layer has taken more than a few milliseconds to render it's
948  // a result of network requests, and the tile manager class handles these gracefully for us)
949  return context.lastRenderingTimeMs <= 1000;
950 }
951 
QgsMapLayer::crsHtmlMetadata
QString crsHtmlMetadata() const
Returns a HTML fragment containing the layer's CRS metadata, for use in the htmlMetadata() method.
Definition: qgsmaplayer.cpp:2372
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QgsMapBoxGlStyleConversionContext::setTargetUnit
void setTargetUnit(QgsUnitTypes::RenderUnit targetUnit)
Sets the target unit type.
Definition: qgsmapboxglstyleconverter.cpp:3308
QgsVectorTileLayer::loadDefaultMetadata
QString loadDefaultMetadata(bool &resultFlag) override
Retrieve the default metadata for this layer if one exists (either as a .qmd file on disk or as a rec...
Definition: qgsvectortilelayer.cpp:704
QgsMapLayer::readCommonStyle
void readCommonStyle(const QDomElement &layerElement, const QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories)
Read style data common to all layer types.
Definition: qgsmaplayer.cpp:1869
QgsVectorTileLayer::LayerOptions
Setting options for loading vector tile layers.
Definition: qgsvectortilelayer.h:96
QgsMapBoxGlStyleConverter::renderer
QgsVectorTileRenderer * renderer() const
Returns a new instance of a vector tile renderer representing the converted style,...
Definition: qgsmapboxglstyleconverter.cpp:3272
QgsDataSourceUri
Class for storing the component parts of a RDBMS data source URI (e.g. a Postgres data source).
Definition: qgsdatasourceuri.h:37
QgsLayerMetadata::setRights
void setRights(const QStringList &rights)
Sets a list of rights (attribution or copyright strings) associated with the resource.
Definition: qgslayermetadata.cpp:56
QgsVectorTileLayer
Implements a map layer that is dedicated to rendering of vector tiles. Vector tiles compared to "ordi...
Definition: qgsvectortilelayer.h:84
QgsCoordinateTransformContext
Contains information about the context in which a coordinate transform is executed.
Definition: qgscoordinatetransformcontext.h:57
QgsVectorTileLayer::sourceType
QString sourceType() const
Returns type of the data source.
Definition: qgsvectortilelayer.h:167
QgsDataProvider::ProviderOptions
Setting options for creating vector data providers.
Definition: qgsdataprovider.h:107
QgsPainting::BlendMode
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer.
Definition: qgspainting.h:49
QgsMapLayer::Labeling
@ Labeling
Labeling.
Definition: qgsmaplayer.h:163
QgsTileXYZ
Stores coordinates of a tile in a tile matrix set. Tile matrix is identified by the zoomLevel(),...
Definition: qgstiles.h:37
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsDataProvider
Abstract base class for spatial data provider implementations.
Definition: qgsdataprovider.h:40
QgsVectorTileLayer::dataProvider
QgsDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectortilelayer.cpp:332
QgsTileRange
Range of tiles in a tile matrix to be rendered. The selection is rectangular, given by start/end row ...
Definition: qgstiles.h:70
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMapLayer::opacity
double opacity
Definition: qgsmaplayer.h:82
QgsMapLayer::blendMode
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
Definition: qgsmaplayer.cpp:320
QgsLayerMetadataFormatter::historySectionHtml
QString historySectionHtml() const
Formats the "History" section according to a metadata object.
Definition: qgslayermetadataformatter.cpp:229
QgsLayerMetadataFormatter
Class for metadata formatter.
Definition: qgslayermetadataformatter.h:33
qgsblockingnetworkrequest.h
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
qgsvectortilelabeling.h
QgsLayerMetadata
A structured metadata store for a map layer.
Definition: qgslayermetadata.h:56
QgsMapLayerType
QgsMapLayerType
Types of layers that can be added to a map.
Definition: qgis.h:46
QgsVectorTileLayer::setRenderer
void setRenderer(QgsVectorTileRenderer *r)
Sets renderer for the map layer.
Definition: qgsvectortilelayer.cpp:885
QgsBlockingNetworkRequest::reply
QgsNetworkReplyContent reply() const
Returns the content of the network reply, after a get(), post(), head() or put() request has been mad...
Definition: qgsblockingnetworkrequest.h:193
QgsVtpkTiles
Utility class for reading and writing ESRI VTPK files.
Definition: qgsvtpktiles.h:37
qgsvtpktiles.h
QgsVectorTileBasicRenderer
The default vector tile renderer implementation. It has an ordered list of "styles",...
Definition: qgsvectortilebasicrenderer.h:127
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsArcGisRestUtils::convertSpatialReference
static QgsCoordinateReferenceSystem convertSpatialReference(const QVariantMap &spatialReferenceMap)
Converts a spatial reference JSON definition to a QgsCoordinateReferenceSystem value.
Definition: qgsarcgisrestutils.cpp:403
QgsVectorTileBasicLabeling
Basic labeling configuration for vector tile layers. It contains a definition of a list of labeling s...
Definition: qgsvectortilebasiclabeling.h:107
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
QgsAbstractMetadataBase::addLink
void addLink(const QgsAbstractMetadataBase::Link &link)
Adds an individual link to the existing links.
Definition: qgsabstractmetadatabase.cpp:158
QgsVectorTileLayer::~QgsVectorTileLayer
~QgsVectorTileLayer() override
QgsLayerMetadataFormatter::contactsSectionHtml
QString contactsSectionHtml() const
Formats the "Contacts" section according to a metadata object.
Definition: qgslayermetadataformatter.cpp:50
QgsMapLayer::setBlendMode
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
Definition: qgsmaplayer.cpp:310
QgsMapLayer::isValid
bool isValid
Definition: qgsmaplayer.h:81
QgsVectorTileLayerRenderer
This class provides map rendering functionality for vector tile layers. In render() function (assumed...
Definition: qgsvectortilelayerrenderer.h:43
QgsAbstractMetadataBase::setTitle
void setTitle(const QString &title)
Sets the human readable title (name) of the resource, typically displayed in search results.
Definition: qgsabstractmetadatabase.cpp:56
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsTileMatrixSet::tileMatrix
QgsTileMatrix tileMatrix(int zoom) const
Returns the tile matrix corresponding to the specified zoom.
Definition: qgstiles.cpp:148
QgsVectorTileMatrixSet::fromEsriJson
bool fromEsriJson(const QVariantMap &json)
Initializes the tile structure settings from an ESRI REST VectorTileService json map.
Definition: qgsvectortilematrixset.cpp:29
QgsMapLayer::setMetadata
virtual void setMetadata(const QgsLayerMetadata &metadata)
Sets the layer's metadata store.
Definition: qgsmaplayer.cpp:2128
QgsMapLayer::setCrs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Definition: qgsmaplayer.cpp:937
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsVectorTileLayer::clone
QgsVectorTileLayer * clone() const override
Returns a new instance equivalent to this one except for the id which is still unique.
Definition: qgsvectortilelayer.cpp:324
QgsSetRequestInitiatorClass
#define QgsSetRequestInitiatorClass(request, _class)
Definition: qgsnetworkaccessmanager.h:45
QgsTileMatrixSet::dropMatricesOutsideZoomRange
void dropMatricesOutsideZoomRange(int minimumZoom, int maximumZoom)
Deletes any existing matrices which fall outside the zoom range specified by minimumZoom to maximumZo...
Definition: qgstiles.cpp:180
QgsMapBoxGlStyleConverter::errorMessage
QString errorMessage() const
Returns a descriptive error message if an error was encountered during the style conversion,...
Definition: qgsmapboxglstyleconverter.h:227
QgsMapLayer::mProviderKey
QString mProviderKey
Data provider key (name of the data provider)
Definition: qgsmaplayer.h:1982
QgsBlockingNetworkRequest::ServerExceptionError
@ ServerExceptionError
An exception was raised by the server.
Definition: qgsblockingnetworkrequest.h:57
QgsMapLayer::Rendering
@ Rendering
Rendering: scale visibility, simplify method, opacity.
Definition: qgsmaplayer.h:170
qgsmapboxglstyleconverter.h
QgsMapLayerRenderer
Base class for utility classes that encapsulate information necessary for rendering of map layers.
Definition: qgsmaplayerrenderer.h:54
qgsmbtiles.h
QgsTileMatrixSet::maximumZoom
int maximumZoom() const
Returns the maximum zoom level for tiles present in the set.
Definition: qgstiles.cpp:169
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1864
QgsMapBoxGlStyleConverter::convert
Result convert(const QVariantMap &style, QgsMapBoxGlStyleConversionContext *context=nullptr)
Converts a JSON style map, and returns the resultant status of the conversion.
Definition: qgsmapboxglstyleconverter.cpp:47
QgsLayerMetadataFormatter::linksSectionHtml
QString linksSectionHtml() const
Formats the "Links" section according to a metadata object.
Definition: qgslayermetadataformatter.cpp:255
QgsVectorTileLayer::encodedSource
QString encodedSource(const QString &source, const QgsReadWriteContext &context) const FINAL
Called by writeLayerXML(), used by derived classes to encode provider's specific data source to proje...
Definition: qgsvectortilelayer.cpp:753
qgsmaplayerfactory.h
QgsPainting::getBlendModeEnum
static QgsPainting::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
Definition: qgspainting.cpp:80
QgsMapBoxGlStyleConverter::Success
@ Success
Conversion was successful.
Definition: qgsmapboxglstyleconverter.h:191
QgsMapLayer::mLayerName
QString mLayerName
Name of the layer - used for display.
Definition: qgsmaplayer.h:1944
qgsvectortilelayer.h
QgsDataSourceUri::param
QString param(const QString &key) const
Returns a generic parameter value corresponding to the specified key.
Definition: qgsdatasourceuri.cpp:834
QgsVtpkTiles::layerMetadata
QgsLayerMetadata layerMetadata() const
Reads layer metadata from the VTPK file.
Definition: qgsvtpktiles.cpp:244
QgsMapBoxGlStyleConversionContext
Context for a MapBox GL style conversion operation.
Definition: qgsmapboxglstyleconverter.h:37
QgsMapLayer::triggerRepaint
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
Definition: qgsmaplayer.cpp:2114
QgsVectorTileLayer::sourcePath
QString sourcePath() const
Returns URL/path of the data source (syntax different to each data source type)
Definition: qgsvectortilelayer.h:169
QgsMapLayer::flags
QgsMapLayer::LayerFlags flags() const
Returns the flags for this layer.
Definition: qgsmaplayer.cpp:150
QgsPathResolver::writePath
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Definition: qgspathresolver.cpp:225
QgsTileMatrix
Defines a matrix of tiles for a single zoom level: it is defined by its size (width *.
Definition: qgstiles.h:107
QgsMapLayerFactory::typeToString
static QString typeToString(QgsMapLayerType type)
Converts a map layer type to a string value.
Definition: qgsmaplayerfactory.cpp:51
QgsMbTiles
Utility class for reading and writing MBTiles files (which are SQLite3 databases).
Definition: qgsmbtiles.h:38
QgsMapLayer::metadata
QgsLayerMetadata metadata
Definition: qgsmaplayer.h:78
QgsVectorTileLayer::createMapRenderer
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
Definition: qgsvectortilelayer.cpp:342
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsVectorTileUtils::checkXYZUrlTemplate
static bool checkXYZUrlTemplate(const QString &url)
Checks whether the URL template string is correct (contains {x}, {y} / {-y}, {z} placeholders)
Definition: qgsvectortileutils.cpp:141
QgsTileMatrixSet::writeXml
virtual QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Writes the set to an XML element.
Definition: qgstiles.cpp:334
QgsMapLayer::setExtent
virtual void setExtent(const QgsRectangle &rect)
Sets the extent.
Definition: qgsmaplayer.cpp:2151
QgsVectorTileLoader::blockingFetchTileRawData
static QList< QgsVectorTileRawData > blockingFetchTileRawData(const QString &sourceType, const QString &sourcePath, const QgsTileMatrix &tileMatrix, const QPointF &viewCenter, const QgsTileRange &range, const QString &authid, const QgsHttpHeaders &headers, QgsFeedback *feedback=nullptr)
Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched...
Definition: qgsvectortileloader.cpp:175
qgsdatasourceuri.h
QgsVectorTileRenderer
Abstract base class for all vector tile renderer implementations.
Definition: qgsvectortilerenderer.h:92
QgsAbstractMetadataBase::setParentIdentifier
void setParentIdentifier(const QString &parentIdentifier)
Sets a reference, URI, URL or some other mechanism to identify the parent resource that this resource...
Definition: qgsabstractmetadatabase.cpp:36
QgsVtpkTiles::open
bool open()
Tries to open the file, returns true on success.
Definition: qgsvtpktiles.cpp:49
QgsMapLayer::readStyleManager
void readStyleManager(const QDomNode &layerNode)
Read style manager's configuration (if any). To be called by subclasses.
Definition: qgsmaplayer.cpp:800
QgsMapLayer::writeCommonStyle
void writeCommonStyle(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) const
Write style data common to all layer types.
Definition: qgsmaplayer.cpp:679
QgsVectorTileRenderer::readXml
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads renderer's properties from given XML element.
QgsVectorTileLayer::renderer
QgsVectorTileRenderer * renderer() const
Returns currently assigned renderer.
Definition: qgsvectortilelayer.cpp:891
qgsnetworkaccessmanager.h
QgsAbstractMetadataBase::setIdentifier
void setIdentifier(const QString &identifier)
Sets the reference, URI, URL or some other mechanism to identify the resource.
Definition: qgsabstractmetadatabase.cpp:26
QgsMapLayer::generalHtmlMetadata
QString generalHtmlMetadata() const
Returns an HTML fragment containing general metadata information, for use in the htmlMetadata() metho...
Definition: qgsmaplayer.cpp:2303
QgsPainting::getCompositionMode
static QPainter::CompositionMode getCompositionMode(QgsPainting::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
Definition: qgspainting.cpp:20
QgsMapBoxGlStyleConversionContext::setSprites
void setSprites(const QImage &image, const QVariantMap &definitions)
Sets the sprite image and definitions JSON to use during conversion.
Definition: qgsmapboxglstyleconverter.cpp:3333
QgsDataSourceUri::setParam
void setParam(const QString &key, const QString &value)
Sets a generic parameter value on the URI.
Definition: qgsdatasourceuri.cpp:789
QgsMapLayer::setOpacity
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Definition: qgsmaplayer.cpp:325
QgsVtpkTiles::spriteDefinition
QVariantMap spriteDefinition() const
Returns the VTPK sprites definitions.
Definition: qgsvtpktiles.cpp:157
Qgis::MapLayerProperty::IsBasemapLayer
@ IsBasemapLayer
Layer is considered a 'basemap' layer, and certain properties of the layer should be ignored when cal...
QgsVtpkTiles::styleDefinition
QVariantMap styleDefinition() const
Returns the VTPK style definition.
Definition: qgsvtpktiles.cpp:124
qgspainting.h
QgsMapLayer::loadDefaultStyle
virtual QString loadDefaultStyle(bool &resultFlag)
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
Definition: qgsmaplayer.cpp:1050
QgsBlockingNetworkRequest::NoError
@ NoError
No error was encountered.
Definition: qgsblockingnetworkrequest.h:54
QgsMapBoxGlStyleConversionContext::spriteDefinitions
QVariantMap spriteDefinitions() const
Returns the sprite definitions to use during conversion.
Definition: qgsmapboxglstyleconverter.cpp:3328
QgsVectorTileLayer::loadDefaultStyle
QString loadDefaultStyle(bool &resultFlag) override
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
Definition: qgsvectortilelayer.cpp:521
QgsVectorTileLayer::setLabeling
void setLabeling(QgsVectorTileLabeling *labeling)
Sets labeling for the map layer.
Definition: qgsvectortilelayer.cpp:896
QgsMapLayer::mDataSource
QString mDataSource
Data source description string, varies by layer type.
Definition: qgsmaplayer.h:1941
QgsDataSourceUri::removeParam
int removeParam(const QString &key)
Removes a generic parameter by key.
Definition: qgsdatasourceuri.cpp:813
QgsVectorTileLayer::writeXml
bool writeXml(QDomNode &layerNode, QDomDocument &doc, const QgsReadWriteContext &context) const override
Called by writeLayerXML(), used by children to write state specific to them to project files.
Definition: qgsvectortilelayer.cpp:366
QgsTileXYZ::zoomLevel
int zoomLevel() const
Returns tile's zoom level (Z)
Definition: qgstiles.h:51
QgsMapBoxGlStyleConverter::labeling
QgsVectorTileLabeling * labeling() const
Returns a new instance of a vector tile labeling representing the converted style,...
Definition: qgsmapboxglstyleconverter.cpp:3277
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
qgsvectortileloader.h
QgsTileMatrixSet::readXml
virtual bool readXml(const QDomElement &element, QgsReadWriteContext &context)
Reads the set from an XML element.
Definition: qgstiles.cpp:303
QgsDataSourceUri::hasParam
bool hasParam(const QString &key) const
Returns true if a parameter with the specified key exists.
Definition: qgsdatasourceuri.cpp:860
QgsBlockingNetworkRequest::TimeoutError
@ TimeoutError
Timeout was reached before a reply was received.
Definition: qgsblockingnetworkrequest.h:56
QgsMapBoxGlStyleConversionContext::setPixelSizeConversionFactor
void setPixelSizeConversionFactor(double sizeConversionFactor)
Sets the pixel size conversion factor, used to scale the original pixel sizes when converting styles.
Definition: qgsmapboxglstyleconverter.cpp:3318
QgsVectorTileLayer::sourceMaxZoom
int sourceMaxZoom() const
Returns maximum zoom level at which source has any valid tiles (negative = unconstrained)
Definition: qgsvectortilelayer.h:174
QgsPathResolver::readPath
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Definition: qgspathresolver.cpp:37
QgsMapLayer::source
QString source() const
Returns the source for the layer.
Definition: qgsmaplayer.cpp:300
QgsBlockingNetworkRequest::get
ErrorCode get(QNetworkRequest &request, bool forceRefresh=false, QgsFeedback *feedback=nullptr)
Performs a "get" operation on the specified request.
Definition: qgsblockingnetworkrequest.cpp:58
QgsMapLayer::writeStyleManager
void writeStyleManager(QDomNode &layerNode, QDomDocument &doc) const
Write style manager's configuration (if exists). To be called by subclasses.
Definition: qgsmaplayer.cpp:809
QgsDataSourceUri::encodedUri
QByteArray encodedUri() const
Returns the complete encoded URI as a byte array.
Definition: qgsdatasourceuri.cpp:614
QgsMapLayer::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
Definition: qgsmaplayer.cpp:951
qgsarcgisrestutils.h
QgsDataSourceUri::setEncodedUri
void setEncodedUri(const QByteArray &uri)
Sets the complete encoded uri.
Definition: qgsdatasourceuri.cpp:636
QgsVectorTileLayer::readSymbology
bool readSymbology(const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) override
Read the symbology for the current layer from the DOM node supplied.
Definition: qgsvectortilelayer.cpp:388
QgsVectorTileLayer::labeling
QgsVectorTileLabeling * labeling() const
Returns currently assigned labeling.
Definition: qgsvectortilelayer.cpp:902
QgsTileXYZ::row
int row() const
Returns tile's row index (Y)
Definition: qgstiles.h:49
QgsTileMatrixSet::crs
QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system associated with the tiles.
Definition: qgstiles.cpp:195
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsMapLayer::invalidateWgs84Extent
void invalidateWgs84Extent()
Invalidates the WGS84 extent.
Definition: qgsmaplayer.cpp:2294
qgsvectortilelayerrenderer.h
QgsMapLayer::Symbology
@ Symbology
Symbology.
Definition: qgsmaplayer.h:161
QgsMapLayerType::VectorTileLayer
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
QgsMapLayer::loadDefaultMetadata
virtual QString loadDefaultMetadata(bool &resultFlag)
Retrieve the default metadata for this layer if one exists (either as a .qmd file on disk or as a rec...
Definition: qgsmaplayer.cpp:1040
qgslayermetadataformatter.h
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
qgsvectortilebasicrenderer.h
QgsVectorTileLayer::getRawTile
QByteArray getRawTile(QgsTileXYZ tileID)
Fetches raw tile data for the give tile coordinates.
Definition: qgsvectortilelayer.cpp:870
QgsVectorTileLayer::decodedSource
QString decodedSource(const QString &source, const QString &provider, const QgsReadWriteContext &context) const FINAL
Called by readLayerXML(), used by derived classes to decode provider's specific data source from proj...
Definition: qgsvectortilelayer.cpp:783
QgsVectorTileMatrixSet::fromWebMercator
static QgsVectorTileMatrixSet fromWebMercator(int minimumZoom=0, int maximumZoom=14)
Returns a vector tile structure corresponding to the standard web mercator/GoogleCRS84Quad setup.
Definition: qgsvectortilematrixset.cpp:22
QgsVectorTileLayer::properties
Qgis::MapLayerProperties properties() const override
Returns the map layer properties of this layer.
Definition: qgsvectortilelayer.cpp:529
QgsNetworkReplyContent::content
QByteArray content() const
Returns the reply content.
Definition: qgsnetworkreply.h:171
QgsNetworkReplyContent
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between...
Definition: qgsnetworkreply.h:28
QgsVectorTileLayer::setTransformContext
void setTransformContext(const QgsCoordinateTransformContext &transformContext) override
Sets the coordinate transform context to transformContext.
Definition: qgsvectortilelayer.cpp:512
QgsTileMatrixSet::minimumZoom
int minimumZoom() const
Returns the minimum zoom level for tiles present in the set.
Definition: qgstiles.cpp:158
QgsVectorTileLabeling
Base class for labeling configuration classes for vector tile layers.
Definition: qgsvectortilelabeling.h:70
QgsVectorTileLayer::sourceMinZoom
int sourceMinZoom() const
Returns minimum zoom level at which source has any valid tiles (negative = unconstrained)
Definition: qgsvectortilelayer.h:172
QgsAbstractMetadataBase::setType
void setType(const QString &type)
Sets the type (nature) of the resource.
Definition: qgsabstractmetadatabase.cpp:46
QgsVectorTileLayer::readXml
bool readXml(const QDomNode &layerNode, QgsReadWriteContext &context) override
Called by readLayerXML(), used by children to read state specific to them from project files.
Definition: qgsvectortilelayer.cpp:347
QgsVectorTileBasicRenderer::simpleStyleWithRandomColors
static QList< QgsVectorTileBasicRendererStyle > simpleStyleWithRandomColors()
Returns a list of styles to render all layers, using random colors.
Definition: qgsvectortilebasicrenderer.cpp:302
QgsMapBoxGlStyleConverter::warnings
QStringList warnings() const
Returns a list of user-friendly warnings generated during the conversion, e.g.
Definition: qgsmapboxglstyleconverter.h:235
QgsDataSourceUri::authConfigId
QString authConfigId() const
Returns any associated authentication configuration ID stored in the URI.
Definition: qgsdatasourceuri.cpp:255
QgsBlockingNetworkRequest::NetworkError
@ NetworkError
A network error occurred.
Definition: qgsblockingnetworkrequest.h:55
qgsjsonutils.h
qgslogger.h
QgsLayerMetadataFormatter::extentSectionHtml
QString extentSectionHtml(const bool showSpatialExtent=true) const
Formats the "Extents" section according to a metadata object (extent and temporal).
Definition: qgslayermetadataformatter.cpp:110
QgsVectorTileLayer::QgsVectorTileLayer
QgsVectorTileLayer(const QString &path=QString(), const QString &baseName=QString(), const QgsVectorTileLayer::LayerOptions &options=QgsVectorTileLayer::LayerOptions())
Constructs a new vector tile layer.
Definition: qgsvectortilelayer.cpp:41
qgsvectortileutils.h
QgsMapLayer::setValid
void setValid(bool valid)
Sets whether layer is valid or not.
Definition: qgsmaplayer.cpp:2061
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
qgsvectortilebasiclabeling.h
QgsLayerMetadataFormatter::accessSectionHtml
QString accessSectionHtml() const
Formats the "Access" section according to a metadata object.
Definition: qgslayermetadataformatter.cpp:27
QgsVectorTileLayer::htmlMetadata
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
Definition: qgsvectortilelayer.cpp:814
QgsVectorTileLabeling::readXml
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads labeling properties from given XML element.
QgsVtpkTiles::spriteImage
QImage spriteImage() const
Returns the VTPK sprite image, if it exists.
Definition: qgsvtpktiles.cpp:200
QgsBlockingNetworkRequest
A thread safe class for performing blocking (sync) network requests, with full support for QGIS proxy...
Definition: qgsblockingnetworkrequest.h:46
QgsLayerMetadataFormatter::identificationSectionHtml
QString identificationSectionHtml() const
Formats the "Identification" section according to a metadata object.
Definition: qgslayermetadataformatter.cpp:180
QgsMapBoxGlStyleConverter
Handles conversion of MapBox GL styles to QGIS vector tile renderers and labeling settings.
Definition: qgsmapboxglstyleconverter.h:172
QgsVectorTileLayer::writeSymbology
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, StyleCategories categories=AllStyleCategories) const override
Write the style for the layer into the document provided.
Definition: qgsvectortilelayer.cpp:465
QgsReadWriteContext::pathResolver
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
Definition: qgsreadwritecontext.cpp:47
QgsTileXYZ::column
int column() const
Returns tile's column index (X)
Definition: qgstiles.h:47
QgsDataSourceUri::httpHeaders
QgsHttpHeaders httpHeaders() const
Returns http headers.
Definition: qgsdatasourceuri.h:345
QgsMapLayer::error
virtual QgsError error() const
Gets current status error.
Definition: qgsmaplayer.cpp:2014
QgsJsonUtils::parseJson
static QVariant parseJson(const std::string &jsonString)
Converts JSON jsonString to a QVariant, in case of parsing error an invalid QVariant is returned and ...
Definition: qgsjsonutils.cpp:456