28 #include <nlohmann/json.hpp> 
   46     mRootTileMatrix = tileMatrix;
 
   57     mErrorMessage = tr( 
"Invalid min. zoom level" );
 
   62     mErrorMessage = tr( 
"Invalid max. zoom level" );
 
   66   std::unique_ptr<QgsMbTiles> mbtiles;
 
   71   QString sourceType = dsUri.
param( QStringLiteral( 
"type" ) );
 
   72   QString sourcePath = dsUri.
param( QStringLiteral( 
"url" ) );
 
   73   if ( sourceType == QLatin1String( 
"xyz" ) )
 
   76     sourcePath = QUrl( sourcePath ).toLocalFile();
 
   80       mErrorMessage = tr( 
"Invalid template for XYZ: " ) + sourcePath;
 
   84   else if ( sourceType == QLatin1String( 
"mbtiles" ) )
 
   90     mErrorMessage = tr( 
"Unsupported source type for writing: " ) + sourceType;
 
  100       mErrorMessage = tr( 
"Failed to calculate output extent" );
 
  106   int tilesToCreate = 0;
 
  107   for ( 
int zoomLevel = mMinZoom; zoomLevel <= mMaxZoom; ++zoomLevel )
 
  112     tilesToCreate += ( tileRange.
endRow() - tileRange.
startRow() + 1 ) *
 
  116   if ( tilesToCreate == 0 )
 
  118     mErrorMessage = tr( 
"No tiles to generate" );
 
  124     if ( !mbtiles->create() )
 
  126       mErrorMessage = tr( 
"Failed to create MBTiles file: " ) + sourcePath;
 
  131     mbtiles->setMetadataValue( 
"format", 
"pbf" );
 
  132     mbtiles->setMetadataValue( 
"json", mbtilesJsonSchema() );
 
  135     const QStringList metaKeys = mMetadata.keys();
 
  136     for ( 
const QString &key : metaKeys )
 
  138       mbtiles->setMetadataValue( key, mMetadata[key].toString() );
 
  142     if ( !mMetadata.contains( 
"name" ) )
 
  143       mbtiles->setMetadataValue( 
"name",  
"unnamed" );  
 
  144     if ( !mMetadata.contains( 
"minzoom" ) )
 
  145       mbtiles->setMetadataValue( 
"minzoom", QString::number( mMinZoom ) );
 
  146     if ( !mMetadata.contains( 
"maxzoom" ) )
 
  147       mbtiles->setMetadataValue( 
"maxzoom", QString::number( mMaxZoom ) );
 
  148     if ( !mMetadata.contains( 
"bounds" ) )
 
  155         QString boundsStr = QString( 
"%1,%2,%3,%4" )
 
  158         mbtiles->setMetadataValue( 
"bounds", boundsStr );
 
  165     if ( !mMetadata.contains( 
"crs" ) )
 
  166       mbtiles->setMetadataValue( 
"crs",  mRootTileMatrix.
crs().
authid() );
 
  169   int tilesCreated = 0;
 
  170   for ( 
int zoomLevel = mMinZoom; zoomLevel <= mMaxZoom; ++zoomLevel )
 
  175     for ( 
int row = tileRange.
startRow(); row <= tileRange.
endRow(); ++row )
 
  183         for ( 
const Layer &layer : std::as_const( mLayers ) )
 
  185           if ( ( layer.minZoom() >= 0 && zoomLevel < layer.minZoom() ) ||
 
  186                ( layer.maxZoom() >= 0 && zoomLevel > layer.maxZoom() ) )
 
  189           encoder.
addLayer( layer.layer(), feedback, layer.filterExpression(), layer.layerName() );
 
  194           mErrorMessage = tr( 
"Operation has been canceled" );
 
  198         QByteArray tileData = encoder.
encode();
 
  203           feedback->
setProgress( 
static_cast<double>( tilesCreated ) / tilesToCreate * 100 );
 
  206         if ( tileData.isEmpty() )
 
  212         if ( sourceType == QLatin1String( 
"xyz" ) )
 
  214           if ( !writeTileFileXYZ( sourcePath, tileID, tileMatrix, tileData ) )
 
  219           QByteArray gzipTileData;
 
  221           int rowTMS = pow( 2, tileID.
zoomLevel() ) - tileID.
row() - 1;
 
  222           mbtiles->setTileData( tileID.
zoomLevel(), tileID.
column(), rowTMS, gzipTileData );
 
  235   for ( 
const Layer &layer : mLayers )
 
  247       QgsDebugMsg( 
"Failed to reproject layer extent to destination CRS" );
 
  253 bool QgsVectorTileWriter::writeTileFileXYZ( 
const QString &sourcePath, 
QgsTileXYZ tileID, 
const QgsTileMatrix &tileMatrix, 
const QByteArray &tileData )
 
  258   QFileInfo fi( filePath );
 
  259   QDir fileDir = fi.dir();
 
  260   if ( !fileDir.exists() )
 
  262     if ( !fileDir.mkpath( 
"." ) )
 
  264       mErrorMessage = tr( 
"Cannot create directory " ) + fileDir.path();
 
  270   if ( !f.open( QIODevice::WriteOnly ) )
 
  272     mErrorMessage = tr( 
"Cannot open file for writing " ) + filePath;
 
  282 QString QgsVectorTileWriter::mbtilesJsonSchema()
 
  284   QVariantList arrayLayers;
 
  285   for ( 
const Layer &layer : std::as_const( mLayers ) )
 
  290     QVariantMap fieldsObj;
 
  293       QString fieldTypeStr;
 
  295         fieldTypeStr = QStringLiteral( 
"Boolean" );
 
  297         fieldTypeStr = QStringLiteral( 
"Number" );
 
  299         fieldTypeStr = QStringLiteral( 
"String" );
 
  304     QVariantMap layerObj;
 
  305     layerObj[
"id"] = vl->
name();
 
  306     layerObj[
"fields"] = fieldsObj;
 
  307     arrayLayers.append( layerObj );
 
  311   rootObj[
"vector_layers"] = arrayLayers;
 
  327     if ( ( layer.minZoom() >= 0 && zoomLevel < layer.minZoom() ) ||
 
  328          ( layer.maxZoom() >= 0 && zoomLevel > layer.maxZoom() ) )
 
  331     encoder.
addLayer( layer.layer(), feedback, layer.filterExpression(), layer.layerName() );
 
This class represents a coordinate reference system (CRS).
QString authid() const
Returns the authority identifier for the CRS.
Custom exception class for Coordinate Reference System related exceptions.
Class for storing the component parts of a RDBMS data source URI (e.g.
void setEncodedUri(const QByteArray &uri)
Sets the complete encoded uri.
QString param(const QString &key) const
Returns a generic parameter value corresponding to the specified key.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
static json jsonFromVariant(const QVariant &v)
Converts a QVariant v to a json object.
QgsCoordinateReferenceSystem crs
Utility class for reading and writing MBTiles files (which are SQLite3 databases).
static bool encodeGzip(const QByteArray &bytesIn, QByteArray &bytesOut)
Encodes gzip byte stream, returns true on success. Useful for writing vector tiles.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
Defines a matrix of tiles for a single zoom level: it is defined by its size (width *.
QgsTileRange tileRangeFromExtent(const QgsRectangle &mExtent)
Returns tile range that fully covers the given extent.
static QgsTileMatrix fromWebMercator(int zoomLevel)
Returns a tile matrix for the usual web mercator.
QgsCoordinateReferenceSystem crs() const
Returns the authority identifier for the CRS of the tile matrix.
bool isRootTileMatrix() const
Returns the root status of the tile matrix (zoom level == 0)
static QgsTileMatrix fromTileMatrix(const int &zoomLevel, const QgsTileMatrix &tileMatrix)
Returns a tile matrix based on another one.
Range of tiles in a tile matrix to be rendered.
int endColumn() const
Returns index of the last column in the range.
int endRow() const
Returns index of the last row in the range.
int startRow() const
Returns index of the first row in the range.
int startColumn() const
Returns index of the first column in the range.
Stores coordinates of a tile in a tile matrix set.
int zoomLevel() const
Returns tile's zoom level (Z)
int column() const
Returns tile's column index (X)
int row() const
Returns tile's row index (Y)
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
Handles conversion of vector features to Mapbox vector tiles encoding.
void addLayer(QgsVectorLayer *layer, QgsFeedback *feedback=nullptr, QString filterExpression=QString(), QString layerName=QString())
Fetches data from vector layer for the given tile, does reprojection and clipping.
void setTileBuffer(int buffer)
Sets size of the buffer zone around tile edges in integer tile coordinates.
void setResolution(int extent)
Sets the resolution of coordinates of geometries within the tile.
QByteArray encode() const
Encodes MVT using data stored previously with addLayer() calls.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets coordinate transform context for transforms between layers and tile matrix CRS.
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} for TM...
Configuration of a single input vector layer to be included in the output.
bool setRootTileMatrix(const QgsTileMatrix &tileMatrix)
Sets zoom level 0 tile matrix.
QgsRectangle fullExtent() const
Returns calculated extent that combines extent of all input layers.
QByteArray writeSingleTile(QgsTileXYZ tileID, QgsFeedback *feedback=nullptr, int buffer=256, int resolution=4096) const
Encodes single MVT tile.
bool writeTiles(QgsFeedback *feedback=nullptr)
Writes vector tiles according to the configuration.