예제 #1
0
    def processAlgorithm(self, parameters, context, feedback):
        crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
        extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
        value = self.parameterAsDouble(parameters, self.NUMBER, context)
        pixelSize = self.parameterAsDouble(parameters, self.PIXEL_SIZE, context)

        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        outputFormat = QgsRasterFileWriter.driverForExtension(os.path.splitext(outputFile)[1])

        rows = max([math.ceil(extent.height() / pixelSize) + 1, 1.0])
        cols = max([math.ceil(extent.width() / pixelSize) + 1, 1.0])

        writer = QgsRasterFileWriter(outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float32, cols, rows, extent, crs)
        provider.setNoDataValue(1, -9999)

        data = [value] * cols
        block = QgsRasterBlock(Qgis.Float32, cols, 1)
        block.setData(struct.pack('{}f'.format(len(data)), *data))

        total = 100.0 / rows if rows else 0
        for i in range(rows):
            if feedback.isCanceled():
                break

            provider.writeBlock(block, 1, 0, i)
            feedback.setProgress(int(i * rows))

        provider.setEditable(False)

        return {self.OUTPUT: outputFile}
예제 #2
0
    def processAlgorithm(self, parameters, context, feedback):
        crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
        extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
        value = self.parameterAsDouble(parameters, self.NUMBER, context)
        pixelSize = self.parameterAsDouble(parameters, self.PIXEL_SIZE, context)

        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        outputFormat = QgsRasterFileWriter.driverForExtension(os.path.splitext(outputFile)[1])

        rows = max([math.ceil(extent.height() / pixelSize) + 1, 1.0])
        cols = max([math.ceil(extent.width() / pixelSize) + 1, 1.0])

        writer = QgsRasterFileWriter(outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float32, cols, rows, extent, crs)
        provider.setNoDataValue(1, -9999)

        data = [value] * cols
        block = QgsRasterBlock(Qgis.Float32, cols, 1)
        block.setData(struct.pack('{}f'.format(len(data)), *data))

        total = 100.0 / rows if rows else 0
        for i in range(rows):
            if feedback.isCanceled():
                break

            provider.writeBlock(block, 1, 0, i)
            feedback.setProgress(int(i * rows))

        provider.setEditable(False)

        return {self.OUTPUT: outputFile}
예제 #3
0
    def processAlgorithm(self, parameters, context, feedback):

        layer = self.parameterAsMeshLayer(parameters, self.INPUT_LAYER,
                                          context)
        dataset = parameters[self.INPUT_DATASET_GROUP]
        timestep = parameters[self.INPUT_TIMESTEP]

        mupp = self.parameterAsDouble(parameters, self.MAP_UNITS_PER_PIXEL,
                                      context)

        extent = self.parameterAsExtent(parameters, self.INPUT_EXTENT, context)

        output_layer = self.parameterAsOutputLayer(parameters, self.OUTPUT,
                                                   context)

        if dataset is None:
            raise QgsProcessingException(u'No dataset group selected')

        width = extent.width() / mupp
        height = extent.height() / mupp
        map_settings = qgis.utils.iface.mapCanvas().mapSettings()
        crs = map_settings.destinationCrs()
        transform_context = QgsProject.instance().transformContext()
        output_format = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(output_layer)[1])

        rfw = QgsRasterFileWriter(output_layer)
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(output_format)
        rdp = rfw.createOneBandRaster(Qgis.Float64, width, height, extent, crs)
        if rdp is None:
            raise QgsProcessingException(
                self.tr("Could not create raster output: {}").format(
                    output_layer))
        if not rdp.isValid():
            raise QgsProcessingException(
                self.tr("Could not create raster output {}: {}").format(
                    output_layer,
                    rdp.error().message(QgsErrorMessage.Text)))
        rdp.setEditable(True)

        nr_timesteps = layer.dataProvider().datasetCount(
            QgsMeshDatasetIndex(dataset))
        if nr_timesteps == 1:
            timestep = 0
        dataset_index = QgsMeshDatasetIndex(dataset, timestep)
        block = QgsMeshUtils.exportRasterBlock(layer, dataset_index, crs,
                                               transform_context, mupp, extent)
        rdp.writeBlock(block, 1)
        rdp.setNoDataValue(1, block.noDataValue())
        rdp.setEditable(False)
        feedback.setProgress(100)
        return {self.OUTPUT: output_layer}
def exportRaster(parameters):
    # Open layer from inputFile
    inputFile = 'Ugrid:' + '"' + parameters['INPUT_LAYER'] + '"'
    meshfile = inputFile.strip().split('/')[-1]
    meshlayer = meshfile.split('.')[0]
    layer = QgsMeshLayer(inputFile, meshlayer, 'mdal')

    # Check if layer is valid
    if layer.isValid() is True:
        # Get parameters for processing
        dataset = parameters['INPUT_GROUP']
        timestep = parameters['INPUT_TIMESTEP']
        mupp = parameters['MAP_UNITS_PER_PIXEL']
        extent = layer.extent()
        output_layer = parameters['OUTPUT_RASTER']
        width = extent.width() / mupp
        height = extent.height() / mupp
        crs = layer.crs()
        crs.createFromSrid(4326)
        transform_context = QgsProject.instance().transformContext()
        output_format = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(output_layer)[1])

        # Open output file for writing
        rfw = QgsRasterFileWriter(output_layer)
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(output_format)

        # Create one band raster
        rdp = rfw.createOneBandRaster(Qgis.Float64, width, height, extent, crs)

        # Get dataset index
        dataset_index = QgsMeshDatasetIndex(dataset, timestep)

        # Regred mesh layer to raster
        block = QgsMeshUtils.exportRasterBlock(layer, dataset_index, crs,
                                               transform_context, mupp, extent)

        # Write raster to GeoTiff file
        rdp.writeBlock(block, 1)
        rdp.setNoDataValue(1, block.noDataValue())
        rdp.setEditable(False)

        logger.info('Regridded mesh data in ' + meshfile.split('"')[0] +
                    ' to float64 grid, and saved to tiff (' +
                    output_layer.split('/')[-1] + ') file.')

        return (output_layer)

    if layer.isValid() is False:
        raise Exception('Invalid mesh')
예제 #5
0
    def processAlgorithm(self, parameters, context, feedback):
        "Create the test DEM."

        extent = self.extent

        x_min = extent.xMinimum()
        x_max = extent.xMaximum()
        y_min = extent.yMinimum()
        y_max = extent.yMaximum()

        x0 = self.center.x()
        y0 = self.center.y()

        outputFormat = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(self.outputFile)[1])

        rows = max([np.ceil(extent.height() / self.dy), 1.0])
        cols = max([np.ceil(extent.width() / self.dx), 1.0])

        writer = QgsRasterFileWriter(self.outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float64, cols, rows, extent,
                                              self.crs)
        provider.setNoDataValue(1, -9999)

        _, _, data = gaussian_bump(x_min,
                                   x_max,
                                   y_min,
                                   y_max,
                                   self.dx,
                                   self.dy,
                                   x0=x0,
                                   y0=y0,
                                   sigma_x=self.sigma_x,
                                   sigma_y=self.sigma_y)

        provider.write(
            bytes(data.data),
            1,  # band
            cols,  # width
            rows,  # height
            0,
            0)  # offset

        provider.setEditable(False)

        return {self.OUTPUT: self.outputFile}
    def processAlgorithm(self, parameters, context, feedback):
        "Compute orographic precipitation."

        dem = raster_to_array(self.orography, self.bandNumber)

        x, y = grid(self.orography)

        dx = x[1] - x[0]
        dy = y[0] - y[1]  # note: y is decreasing

        assert dx > 0
        assert dy > 0

        P = self.model.run(dem, dx, dy, self.truncate)

        outputFormat = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(self.outputFile)[1])

        writer = QgsRasterFileWriter(self.outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float64, x.size, y.size,
                                              self.orography.extent(),
                                              self.orography.crs())
        provider.setNoDataValue(1, -9999)

        provider.write(
            bytes(P.data),
            1,  # band
            x.size,  # width
            y.size,  # height
            0,
            0)  # offset

        provider.setEditable(False)

        return {self.OUTPUT: self.outputFile}
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        if self.parameterAsRasterLayer(parameters, self.INITIAL_ROAD_NETWORK,
                                       context):
            initial_road_network_raster = self.parameterAsRasterLayer(
                parameters, self.INITIAL_ROAD_NETWORK, context)
        else:
            initial_road_network_raster = None

        basic_distance_cost = self.parameterAsDouble(parameters,
                                                     self.BASIC_DISTANCE_COST,
                                                     context)

        if self.parameterAsRasterLayer(parameters,
                                       self.COARSE_ELEVATION_RASTER, context):
            coarse_elevation_raster = self.parameterAsRasterLayer(
                parameters, self.COARSE_ELEVATION_RASTER, context)
        else:
            coarse_elevation_raster = None

        if self.parameterAsMatrix(parameters, self.COARSE_ELEVATION_COSTS,
                                  context):
            coarse_elevation_costs = self.parameterAsMatrix(
                parameters, self.COARSE_ELEVATION_COSTS, context)
            coarse_elevation_costs = CostRasterCreatorHelper.CollapsedTableToMatrix(
                coarse_elevation_costs, 3)
        else:
            coarse_elevation_costs = None

        if self.parameterAsRasterLayer(parameters, self.FINE_ELEVATION_RASTER,
                                       context):
            fine_elevation_raster = self.parameterAsRasterLayer(
                parameters, self.FINE_ELEVATION_RASTER, context)
        else:
            fine_elevation_raster = None

        if self.parameterAsMatrix(parameters, self.FINE_ELEVATION_COSTS,
                                  context):
            fine_elevation_costs = self.parameterAsMatrix(
                parameters, self.FINE_ELEVATION_COSTS, context)
            fine_elevation_costs = CostRasterCreatorHelper.CollapsedTableToMatrix(
                fine_elevation_costs, 3)
        else:
            fine_elevation_costs = None

        if self.parameterAsRasterLayer(parameters, self.COARSE_WATER_RASTER,
                                       context):
            coarse_water_raster = self.parameterAsRasterLayer(
                parameters, self.COARSE_WATER_RASTER, context)
        else:
            coarse_water_raster = None

        if self.parameterAsDouble(parameters, self.COARSE_WATER_COST, context):
            coarse_water_cost = self.parameterAsDouble(parameters,
                                                       self.COARSE_WATER_COST,
                                                       context)
        else:
            coarse_water_cost = None

        if self.parameterAsRasterLayer(parameters, self.FINE_WATER_RASTER,
                                       context):
            fine_water_raster = self.parameterAsRasterLayer(
                parameters, self.FINE_WATER_RASTER, context)
        else:
            fine_water_raster = None

        if self.parameterAsDouble(parameters, self.FINE_WATER_COST, context):
            fine_water_cost = self.parameterAsDouble(parameters,
                                                     self.FINE_WATER_COST,
                                                     context)
        else:
            fine_water_cost = None

        if self.parameterAsRasterLayer(parameters, self.SOIL_RASTER, context):
            soil_raster = self.parameterAsRasterLayer(parameters,
                                                      self.SOIL_RASTER,
                                                      context)
        else:
            soil_raster = None

        if self.parameterAsRasterLayer(parameters, self.ADDITIONAL_COST_RASTER,
                                       context):
            special_raster = self.parameterAsRasterLayer(
                parameters, self.ADDITIONAL_COST_RASTER, context)
        else:
            special_raster = None

        feedback.pushInfo(self.tr("Checking inputs..."))
        # If source was not found, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSourceError method to return a standard
        # helper text for when a source cannot be evaluated
        if basic_distance_cost is None or basic_distance_cost == 0:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.BASIC_DISTANCE_COST))

        # Now, we check to see if the CRS, extent and resolution of every raster is equal, so that their align properly.
        listOfRastersToCheck = list()
        if initial_road_network_raster is not None:
            listOfRastersToCheck.append(initial_road_network_raster)
        if coarse_elevation_raster is not None:
            listOfRastersToCheck.append(coarse_elevation_raster)
        if fine_elevation_raster is not None:
            listOfRastersToCheck.append(fine_elevation_raster)
        if coarse_water_raster is not None:
            listOfRastersToCheck.append(coarse_water_raster)
        if fine_water_raster is not None:
            listOfRastersToCheck.append(fine_water_raster)
        if soil_raster is not None:
            listOfRastersToCheck.append(soil_raster)
        if special_raster is not None:
            listOfRastersToCheck.append(special_raster)

        if len(listOfRastersToCheck) == 0:
            raise QgsProcessingException(
                self.
                tr("At least one input raster is needed ! Please, input one raster."
                   ))

        # We check that every raster has the same CRS, extent and resolution.
        CostRasterCreatorHelper.CheckRastersCompatibility(listOfRastersToCheck)

        # We also check that the matrix of parameters entered for the coarse elevation costs and fine elevation costs
        # are correct : meaning that there are no holes between the thresholds, and that every lower threshold is lower
        # than the upper threshold.
        if coarse_elevation_costs is not None:
            CostRasterCreatorHelper.CheckThresholds(coarse_elevation_costs,
                                                    "Coarse elevation costs")
        if fine_elevation_costs is not None:
            CostRasterCreatorHelper.CheckThresholds(fine_elevation_costs,
                                                    "Fine elevation costs")

        # Then, we create the raster blocks
        if initial_road_network_raster is not None:
            initial_road_network_raster_block = CostRasterCreatorHelper.get_all_block(
                initial_road_network_raster)
        else:
            initial_road_network_raster_block = None

        if coarse_elevation_raster is not None:
            coarse_elevation_raster_block = CostRasterCreatorHelper.get_all_block(
                coarse_elevation_raster)
        else:
            coarse_elevation_raster_block = None

        if fine_elevation_raster is not None:
            fine_elevation_raster_block = CostRasterCreatorHelper.get_all_block(
                fine_elevation_raster)
        else:
            fine_elevation_raster_block = None

        if coarse_water_raster is not None:
            coarse_water_raster_block = CostRasterCreatorHelper.get_all_block(
                coarse_water_raster)
        else:
            coarse_water_raster_block = None

        if fine_water_raster is not None:
            fine_water_raster_block = CostRasterCreatorHelper.get_all_block(
                fine_water_raster)
        else:
            fine_water_raster_block = None

        if soil_raster is not None:
            soil_raster_block = CostRasterCreatorHelper.get_all_block(
                soil_raster)
        else:
            soil_raster_block = None

        if special_raster is not None:
            special_raster_block = CostRasterCreatorHelper.get_all_block(
                special_raster)
        else:
            special_raster_block = None

        feedback.pushInfo(self.tr("Preparing output..."))
        # We set the output to be ready : It is a QgsDataProvider
        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT,
                                                 context)
        outputFormat = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(outputFile)[1])

        crs = listOfRastersToCheck[0].crs()
        extent = listOfRastersToCheck[0].extent()
        rows = max([
            math.ceil(extent.height() /
                      listOfRastersToCheck[0].rasterUnitsPerPixelY()), 1.0
        ])
        cols = max([
            math.ceil(extent.width() /
                      listOfRastersToCheck[0].rasterUnitsPerPixelX()), 1.0
        ])
        # We will need this value for the fine water computation later
        pixelSide = (listOfRastersToCheck[0].rasterUnitsPerPixelY() +
                     listOfRastersToCheck[0].rasterUnitsPerPixelX()) / 2

        writer = QgsRasterFileWriter(outputFile)
        writer.setOutputProviderKey('gdal')
        writer.setOutputFormat(outputFormat)
        provider = writer.createOneBandRaster(Qgis.Float32, cols, rows, extent,
                                              crs)

        if provider is None:
            raise QgsProcessingException(
                self.tr("Could not create raster output: {}").format(
                    outputFile))
        if not provider.isValid():
            raise QgsProcessingException(
                self.tr("Could not create raster output {}").format(
                    outputFile))

        provider.setNoDataValue(1, -9999)

        # We create the data block for the output raster, and we fill it with the values we need
        dataBlock = QgsRasterBlock(Qgis.Float32, cols, rows)
        # i = float(1.0)

        feedback.pushInfo(self.tr("Calculating cost raster..."))
        progress = 0
        feedback.setProgress(0)
        errorMessages = list()
        for y in range(dataBlock.height()):
            for x in range(dataBlock.width()):
                if feedback.isCanceled():
                    raise QgsProcessingException(
                        self.tr("ERROR: Operation was cancelled."))

                    # If there is a road already on this pixel, then the cost is 0.
                if initial_road_network_raster_block is not None and \
                     (initial_road_network_raster_block.value(y,
                                                              x) != 0 and not initial_road_network_raster_block.isNoData(
                         y, x)):
                    finalValue = 0

                # If there is a water body on this pixel, we stop everything :
                # The cost will be the construction of a bridge
                elif coarse_water_raster_block is not None and coarse_water_raster_block.value(
                        y, x) != 0:
                    if coarse_water_cost is not None:
                        finalValue = coarse_water_cost
                    else:
                        raise QgsProcessingException(
                            self.
                            tr("A coarse water raster has been given, but no coarse "
                               +
                               "water cost. Please input a coarse water cost.")
                        )
                    # feedback.pushInfo("Seems like there was a road on this pixel. Final value is " + str(finalValue))

                # Else, if we are not on a road or on a body of water...
                else:
                    # We start with the base cost of crossing the pixel
                    finalValue = basic_distance_cost
                    # feedback.pushInfo("No road on this pixel, we put basic distance cost. Final value is " + str(finalValue))
                    # Then, if we have it, we add the soil cost
                    if soil_raster_block is not None:
                        finalValue += soil_raster_block.value(y, x)
                        # feedback.pushInfo("After soils, final value is " + str(finalValue))
                    if special_raster_block is not None:
                        finalValue += special_raster_block.value(y, x)
                    # Then the coarse elevation value
                    if coarse_elevation_raster_block is not None:
                        additionalValue, errorMessage = CostRasterCreatorHelper.CalculateCoarseElevationCost(
                            y, x, coarse_elevation_raster_block,
                            coarse_elevation_costs, pixelSide)
                        finalValue += additionalValue
                        if errorMessage is not None:
                            errorMessages.append(errorMessage)
                        # feedback.pushInfo("After coarse elevation, final value is " + str(finalValue))
                    # Then the fine water value
                    if fine_water_raster_block is not None:
                        finalValue += CostRasterCreatorHelper.CalculateFineWaterCost(
                            y, x, fine_water_raster_block, fine_water_cost,
                            pixelSide)
                        # feedback.pushInfo("After fine water, final value is " + str(finalValue))
                    # Then, we multiply everything with the fine elevation cost.
                    if fine_elevation_raster_block is not None:
                        finalValue, errorMessage = CostRasterCreatorHelper.CalculateFineElevationCost(
                            y, x, fine_elevation_raster_block,
                            fine_elevation_costs, finalValue)
                        if errorMessage is not None:
                            errorMessages.append(errorMessage)
                        # feedback.pushInfo("After fine elevation, final value is " + str(finalValue))
                dataBlock.setValue(y, x, float(finalValue))

                progress += 1
                feedback.setProgress(
                    100 * (progress /
                           (dataBlock.height() * dataBlock.width())))

        # We write the values in the provider of our files
        provider.writeBlock(dataBlock, 1)

        # We stop the edition of the output raster
        provider.setEditable(False)

        # We display the warning messages about the thresholds
        if len(errorMessages) > 0:
            above = 0
            below = 0
            for errorMessage in errorMessages:
                if errorMessage == "Above":
                    above += 1
                elif errorMessage == "Below":
                    below += 1
            feedback.pushInfo(
                self.
                tr("WARNING : There were " + str(below) +
                   " situations where the value of a pixel was under"
                   " the lowest threshold given as a parameter; and " +
                   str(above) + " when it was above the"
                   " highest. In those cases, the lowest or highest value of the parameter range was used."
                   " To avoid that, please make sure to use thresholds that cover all of the range of values in"
                   " your rasters."))

        # We make the output
        return {self.OUTPUT: outputFile}
예제 #8
0
    def processAlgorithm(self, parameters, context, feedback):
        '''
        Here is where the processing itself takes place.
        '''

        from PIL import (
            Image,
            ImageDraw,
        )
        import numpy

        source = self.parameterAsSource(parameters, self.INPUT, context)
        resolution = self.parameterAsDouble(parameters, self.RESOLUTION,
                                            context)
        outpath = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        result = {self.OUTPUT: outpath}

        # Compute the number of steps to display within the progress bar
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        # Calculate the output extent
        extent = source.sourceExtent()
        xmin = extent.xMinimum()
        ymax = extent.yMaximum()
        xsize = int((extent.xMaximum() - xmin) / resolution) + 1
        ysize = int((ymax - extent.yMinimum()) / resolution) + 1
        if xsize > 50000 or ysize > 50000:
            feedback.reportError(
                self.tr('Output raster size is too big: {}x{}!').format(
                    xsize, ysize), True)
            # fatalError = true has no effect
            feedback.cancel()
            return result
        feedback.pushConsoleInfo(
            self.tr('Output raster size is {}x{}').format(xsize, ysize))

        # Create output buffer
        density = numpy.zeros((ysize, xsize), dtype=numpy.uint16)
        # Create geometry mask buffer
        mask = Image.new('1', (xsize, ysize), 0)
        draw = ImageDraw.Draw(mask)

        # Iterate over features from source
        features = source.getFeatures()
        for current, feature in enumerate(features):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                return result

            # Convert feature geometry to the image coordinates
            geometry = feature.geometry()
            geometry.convertToSingleType()
            polygon = geometry.asPolygon()
            points = []
            for p in polygon:
                for x, y in p:
                    x = (x - xmin) / resolution
                    y = (ymax - y) / resolution
                    points.append((x, y))

            # Generate geometry mask
            draw.polygon(points, 1)
            # Add geometry mask to the result raster
            density = numpy.add(density, numpy.array(mask))
            # Reset the mask
            draw.rectangle([0, 0, xsize, ysize], fill=0)

            # Update the progress bar
            feedback.setProgress(int(current * total))

        # Write output raster
        writer = QgsRasterFileWriter(outpath)
        provider = writer.createOneBandRaster(Qgis.UInt16, xsize, ysize,
                                              extent, source.sourceCrs())
        provider.write(density.astype('H').tostring(), 1, xsize, ysize, 0, 0)
        density = None
        draw = None
        mask = None

        return result
    def processAlgorithm(self, parameters, context, feedback):

        layer = self.parameterAsMeshLayer(parameters, self.INPUT_LAYER, context)
        dataset = parameters[self.INPUT_DATASET_GROUP]
        timestep = parameters[self.INPUT_TIMESTEP]

        mupp = self.parameterAsDouble(
            parameters,
            self.MAP_UNITS_PER_PIXEL,
            context)

        extent = self.parameterAsExtent(
            parameters,
            self.INPUT_EXTENT,
            context)

        output_layer = self.parameterAsOutputLayer(
            parameters,
            self.OUTPUT,
            context)

        if dataset is None:
            raise QgsProcessingException(u'No dataset group selected')

        width = extent.width()/mupp
        height = extent.height()/mupp
        map_settings = qgis.utils.iface.mapCanvas().mapSettings()
        crs = map_settings.destinationCrs()
        transform_context = QgsProject.instance().transformContext()
        output_format = QgsRasterFileWriter.driverForExtension(os.path.splitext(output_layer)[1])

        rfw = QgsRasterFileWriter(output_layer)
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(output_format)
        rdp = rfw.createOneBandRaster(
            Qgis.Float64,
            width,
            height,
            extent,
            crs
        )
        if rdp is None:
            raise QgsProcessingException(self.tr("Could not create raster output: {}").format(output_layer))
        if not rdp.isValid():
            raise QgsProcessingException(
                self.tr("Could not create raster output {}: {}").format(
                    output_layer,
                    rdp.error().message(QgsErrorMessage.Text)
                )
            )
        rdp.setEditable(True)

        nr_timesteps = layer.dataProvider().datasetCount(QgsMeshDatasetIndex(dataset))
        if nr_timesteps == 1:
            timestep = 0
        dataset_index = QgsMeshDatasetIndex(dataset, timestep)
        block = QgsMeshUtils.exportRasterBlock(
            layer,
            dataset_index,
            crs,
            transform_context,
            mupp,
            extent
        )
        rdp.writeBlock(block, 1)
        rdp.setNoDataValue(1, block.noDataValue())
        rdp.setEditable(False)
        feedback.setProgress(100)
        return {self.OUTPUT: output_layer}