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}
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}
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')
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}
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}