The way I would approach this is to define a source raster and an output raster destination (which can be either a temporary or a file output, then copy the input raster using gdal translate, passing the output raster destination parameter as input. The output from the gdal translate algorithm is what you then pass as the input to the rasterize (overwrite with attribute) algorithm. The only catch is that if the user specifies a temporary output, then the output layer name will be 'Converted' (inherited from the gdal translate output) so you can use a QgsProcessingLayerPostProcessorInterface
sub-class to rename the output layer if necessary. I guess this is something of a workaround (and there may be a better way), but it is still a working solution and, to be honest, the most straightforward one I can think of. You can see a full example below:
from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterField
from qgis.core import QgsProcessingParameterRasterLayer
from qgis.core import QgsProcessingParameterRasterDestination
from qgis.core import QgsProcessingLayerPostProcessorInterface
from qgis.core import QgsRasterLayer
import processing
class Group_output_layers(QgsProcessingAlgorithm):
inputVector = 'input_vector'
field = 'field'
inputRaster = 'source_raster'
outputRaster = 'output_raster'
def name(self):
return 'overwrite_raster_copy'
def displayName(self):
return 'Overwrite raster copy'
def group(self):
return 'Models'
def groupId(self):
return 'Models'
def createInstance(self):
return Group_output_layers()
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterVectorLayer('input_vector', 'Input vector'))
self.addParameter(QgsProcessingParameterField('field', 'Field to use as burn in value', parentLayerParameterName=self.inputVector, type=0))
self.addParameter(QgsProcessingParameterRasterLayer('source_raster', 'Source raster'))
self.addParameter(QgsProcessingParameterRasterDestination('output_raster', 'Output raster'))
def processAlgorithm(self, parameters, context, feedback):
results = {}
outputs = {}
sourceraster = self.parameterAsRasterLayer(parameters, 'source_raster', context)
# Copy source raster with gdal translate
alg1_params = {'INPUT':parameters['source_raster'],
'TARGET_CRS':None,
'NODATA':None,
'COPY_SUBDATASETS':False,
'OPTIONS':'',
'EXTRA':'',
'DATA_TYPE':0,
'OUTPUT':parameters['output_raster']}
outputs['copied_raster']= processing.run("gdal:translate",
alg1_params,
is_child_algorithm=True,
context=context,
feedback=feedback)
# Rasterize (overwrite with attribute)
alg2_params = {'INPUT':parameters[self.inputVector],
'INPUT_RASTER':outputs['copied_raster']['OUTPUT'],
'FIELD':parameters[self.field],
'ADD':False,
'EXTRA':''}
outputs['rasterized_over'] = processing.run("gdal:rasterize_over",
alg2_params,
is_child_algorithm=True,
context=context,
feedback=feedback)
results['OUTPUT']=outputs['rasterized_over']['OUTPUT']
# Use a layer post processor to rename output layer (if memory layer)
if context.willLoadLayerOnCompletion(results['OUTPUT']):
context.layerToLoadOnCompletionDetails(results['OUTPUT']).setPostProcessor(MyLayerPostProcessor.create())
return results
# Courtesy of Nyall Dawson: https://gist.github.com/nyalldawson/26c091dd48b4f8bf56f172efe22cf75f
class MyLayerPostProcessor(QgsProcessingLayerPostProcessorInterface):
instance = None
def postProcessLayer(self, layer, context, feedback): # pylint: disable=unused-argument
if not isinstance(layer, QgsRasterLayer):
return
"""
If output layer is a temporary memory layer, it will have the name 'Converted',
otherwise it will have the user-specified name from the output file location.
So we check the layer name before setting it's name.
"""
if layer.name() == 'Converted':
layer.setName('Rasterized_over')
# Hack to work around sip bug!
@staticmethod
def create() -> 'MyLayerPostProcessor':
"""
Returns a new instance of the post processor, keeping a reference to the sip
wrapper so that sip doesn't get confused with the Python subclass and call
the base wrapper implementation instead... ahhh sip, you wonderful piece of sip
"""
MyLayerPostProcessor.instance = MyLayerPostProcessor()
return MyLayerPostProcessor.instance
Screencast demo:

The code for the MyLayerPostProcessor()
class I adapted from an example by Nyall Dawson in a GitHub gist (which I can't link to as it seems to have been deleted).