33 #include <QtConcurrent> 37 QString QgsRasterizeAlgorithm::name()
const 39 return QStringLiteral(
"rasterize" );
42 QString QgsRasterizeAlgorithm::displayName()
const 44 return QObject::tr(
"Convert map to raster" );
47 QStringList QgsRasterizeAlgorithm::tags()
const 49 return QObject::tr(
"layer,raster,convert,file,map themes,tiles,render" ).split(
',' );
52 QString QgsRasterizeAlgorithm::group()
const 54 return QObject::tr(
"Raster tools" );
57 QString QgsRasterizeAlgorithm::groupId()
const 59 return QStringLiteral(
"rastertools" );
62 void QgsRasterizeAlgorithm::initAlgorithm(
const QVariantMap & )
65 QStringLiteral(
"EXTENT" ),
66 QObject::tr(
"Minimum extent to render" ) ) );
68 QStringLiteral(
"EXTENT_BUFFER" ),
69 QObject::tr(
"Buffer around tiles in map units" ),
70 QgsProcessingParameterNumber::Type::Double,
75 QStringLiteral(
"TILE_SIZE" ),
76 QObject::tr(
"Tile size" ),
77 QgsProcessingParameterNumber::Type::Integer,
82 QStringLiteral(
"MAP_UNITS_PER_PIXEL" ),
83 QObject::tr(
"Map units per pixel" ),
84 QgsProcessingParameterNumber::Type::Double,
89 QStringLiteral(
"MAKE_BACKGROUND_TRANSPARENT" ),
90 QObject::tr(
"Make background transparent" ),
94 QStringLiteral(
"MAP_THEME" ),
95 QObject::tr(
"Map theme to render" ),
100 QStringLiteral(
"LAYERS" ),
101 QObject::tr(
"Layers to render" ),
107 QStringLiteral(
"OUTPUT" ),
108 QObject::tr(
"Output layer" ) ) );
112 QString QgsRasterizeAlgorithm::shortDescription()
const 114 return QObject::tr( R
"(This algorithm rasterizes map canvas content. 115 A map theme can be selected to render a predetermined set of layers with a defined style for each layer. 116 Alternatively, a set of layers layer can be selected if no map theme is set. 117 If neither map theme nor layer is set all the current project layers will be 119 The minimum extent entered will internally be extended to be a multiple of the tile size.)" ); 122 QString QgsRasterizeAlgorithm::shortHelpString() const 124 return QObject::tr( R
"(This algorithm renders the map canvas to a raster file. 125 It's possible to choose the following parameters: 126 - Map theme to render 128 - The minimum extent to render 131 - The output (can be saved to a file or to a temporary file and 132 automatically opened as layer in qgis) 136 QgsRasterizeAlgorithm *QgsRasterizeAlgorithm::createInstance() const 138 return new QgsRasterizeAlgorithm();
145 const QgsRectangle extent { parameterAsExtent( parameters, QStringLiteral(
"EXTENT" ), context, context.
project()->
crs() ) };
146 const int tileSize { parameterAsInt( parameters, QStringLiteral(
"TILE_SIZE" ), context ) };
147 const bool transparent { parameterAsBool( parameters, QStringLiteral(
"MAKE_BACKGROUND_TRANSPARENT" ), context ) };
148 const double mapUnitsPerPixel { parameterAsDouble( parameters, QStringLiteral(
"MAP_UNITS_PER_PIXEL" ), context ) };
149 const double extentBuffer { parameterAsDouble( parameters, QStringLiteral(
"EXTENT_BUFFER" ), context ) };
150 const QString outputLayerFileName { parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context )};
152 int xTileCount {
static_cast<int>( ceil( extent.width() / mapUnitsPerPixel / tileSize ) )};
153 int yTileCount {
static_cast<int>( ceil( extent.height() / mapUnitsPerPixel / tileSize ) )};
154 int width { xTileCount * tileSize };
155 int height { yTileCount * tileSize };
156 int nBands { transparent ? 4 : 3 };
159 if ( driverName.isEmpty() )
164 GDALDriverH hOutputFileDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
165 if ( !hOutputFileDriver )
170 gdal::dataset_unique_ptr hOutputDataset( GDALCreate( hOutputFileDriver, outputLayerFileName.toLocal8Bit().constData(), width, height, nBands, GDALDataType::GDT_Byte, nullptr ) );
171 if ( !hOutputDataset )
177 double geoTransform[6];
178 geoTransform[0] = extent.xMinimum();
179 geoTransform[1] = mapUnitsPerPixel;
181 geoTransform[3] = extent.yMaximum();
183 geoTransform[5] = - mapUnitsPerPixel;
184 GDALSetGeoTransform( hOutputDataset.get(), geoTransform );
186 int red = context.
project()->
readNumEntry( QStringLiteral(
"Gui" ),
"/CanvasColorRedPart", 255 );
187 int green = context.
project()->
readNumEntry( QStringLiteral(
"Gui" ),
"/CanvasColorGreenPart", 255 );
188 int blue = context.
project()->
readNumEntry( QStringLiteral(
"Gui" ),
"/CanvasColorBluePart", 255 );
193 bgColor = QColor( red, green, blue, 0 );
197 bgColor = QColor( red, green, blue );
211 QList<QgsMapLayer *> layers;
212 for (
const auto &lptr : mMapLayers )
214 layers.push_back( lptr.get() );
220 const double extentRatio { mapUnitsPerPixel * tileSize };
221 const int numTiles { xTileCount * yTileCount };
222 const QString fileExtension { QFileInfo( outputLayerFileName ).suffix() };
227 void operator()( uint8_t *ptr )
const 233 QAtomicInt rendered = 0;
234 QMutex rasterWriteLocker;
236 const auto renderJob = [ & ](
const int x,
const int y,
QgsMapSettings mapSettings )
238 QImage image { tileSize, tileSize, QImage::Format::Format_ARGB32 };
241 QPainter painter { &image };
246 image.fill( transparent ? bgColor.rgba() : bgColor.rgb() );
248 extent.xMinimum() + x * extentRatio,
249 extent.yMaximum() - ( y + 1 ) * extentRatio,
250 extent.xMinimum() + ( x + 1 ) * extentRatio,
251 extent.yMaximum() - y * extentRatio
255 job.waitForFinished();
258 if ( !hIntermediateDataset )
263 const int xOffset { x * tileSize };
264 const int yOffset { y * tileSize };
266 std::unique_ptr<uint8_t, CPLDelete> buffer( static_cast< uint8_t * >( CPLMalloc(
sizeof( uint8_t ) * static_cast<size_t>( tileSize * tileSize * nBands ) ) ) );
267 CPLErr err = GDALDatasetRasterIO( hIntermediateDataset.get(),
268 GF_Read, 0, 0, tileSize, tileSize,
270 tileSize, tileSize, GDT_Byte, nBands,
nullptr, 0, 0, 0 );
271 if ( err != CE_None )
277 QMutexLocker locker( &rasterWriteLocker );
278 err = GDALDatasetRasterIO( hOutputDataset.get(),
279 GF_Write, xOffset, yOffset, tileSize, tileSize,
281 tileSize, tileSize, GDT_Byte, nBands,
nullptr, 0, 0, 0 );
283 feedback->
setProgress( static_cast<double>( rendered ) / numTiles * 100.0 );
285 if ( err != CE_None )
293 std::vector<QFuture<void>> futures;
295 for (
int x = 0; x < xTileCount; ++x )
297 for (
int y = 0; y < yTileCount; ++y )
303 futures.push_back( QtConcurrent::run( renderJob, x, y, mapSettings ) );
307 for (
auto &f : futures )
312 return { { QStringLiteral(
"OUTPUT" ), outputLayerFileName } };
320 const QString mapTheme { parameterAsString( parameters, QStringLiteral(
"MAP_THEME" ), context ) };
321 const QList<QgsMapLayer *> mapLayers { parameterAsLayerList( parameters, QStringLiteral(
"LAYERS" ), context ) };
327 mMapLayers.push_back( std::unique_ptr<QgsMapLayer>( ml->clone( ) ) );
331 else if ( ! mapLayers.isEmpty() )
333 for (
const QgsMapLayer *ml : qgis::as_const( mapLayers ) )
335 mMapLayers.push_back( std::unique_ptr<QgsMapLayer>( ml->clone( ) ) );
339 if ( mMapLayers.size() == 0 )
344 mMapLayers.push_back( std::unique_ptr<QgsMapLayer>( ml->clone( ) ) );
347 return mMapLayers.size() > 0;
A boolean parameter for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
A rectangle specified with double values.
Base class for all map layer types.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Set coordinates of the rectangle which should be rendered.
Job implementation that renders everything sequentially using a custom painter.
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
Base class for providing feedback from a processing algorithm.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
QList< QgsMapLayer * > mapThemeVisibleLayers(const QString &name) const
Returns the list of layers that are visible for the specified map theme.
QMap< QString, QString > mapThemeStyleOverrides(const QString &name)
Gets layer style overrides (for QgsMapSettings) of the visible layers for given map theme...
static gdal::dataset_unique_ptr imageToMemoryDataset(const QImage &image)
Converts an image to a GDAL memory dataset by borrowing image data.
void setProgress(double progress)
Sets the current progress for the feedback object.
void setOutputDpi(double dpi)
Sets DPI used for conversion between real world units (e.g. mm) and pixels.
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Set map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
Enable layer opacity and blending effects.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
QgsProject * project() const
Returns the project in which the algorithm is being executed.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
The QgsMapSettings class contains configuration for rendering of the map.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
void setOutputSize(QSize size)
Sets the size of the resulting map image.
QgsMapThemeCollection mapThemeCollection
QgsCoordinateReferenceSystem crs
Enable anti-aliasing for map rendering.
Custom exception class for processing related exceptions.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
void setOutputImageFormat(QImage::Format format)
sets format of internal QImage
A rectangular map extent parameter for processing algorithms.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
A numeric parameter for processing algorithms.
Full WKT2 string, conforming to ISO 19162:2018 / OGC 18-010, with all possible nodes and new keyword ...
Draw map such that there are no problems between adjacent tiles.
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
bool isCanceled() const
Tells whether the operation has been canceled already.
Any map layer type (raster or vector or mesh)
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setLayers(const QList< QgsMapLayer *> &layers)
Set list of layers for map rendering.
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
A map theme parameter for processing algorithms, allowing users to select an existing map theme from ...
Contains information about the context in which a processing algorithm is executed.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.