My workflow in a nutshell: I create cost rasters from starting points along a street network (grass7:r.cost), reclassify them according to their distance values (gdal:rastercalculator) and would like to add up all resulting rasters.
After trying to add up all at once I decided to iterate over, which also needs to happen in memory. However I just fail to make it work. The Input does not get accepted no matter if I use QgsRasterLayer or the direct output of the gdal calculation. Those are definitely valid.
def process_layer(layer, output_prefix, sum_raster): heat_columns = ['0_100', '100_200', '200_300', '300_400'] featurecounter = 0 for feature in layer.getFeatures(): point_id = feature.id() point_geom = feature.geometry() feedback.pushInfo(f"Processing Point ID: {point_id}, Geometry: {point_geom.asWkt()}") coords = point_geom.asPoint() x, y = coords.x(), coords.y() params = {'input': result['output'],'-k': False,'-n': False,'start_coordinates': f"{x},{y}",'max_cost': 400,'null_cost': None,'output': 'TEMPORARY_OUTPUT','nearest': 'TEMPORARY_OUTPUT','outdir': 'TEMPORARY_OUTPUT','GRASS_REGION_CELLSIZE_PARAMETER': 1,'GRASS_RASTER_FORMAT_OPT': '','GRASS_RASTER_FORMAT_META': '','GRASS_SNAP_TOLERANCE_PARAMETER': -1,'GRASS_MIN_AREA_PARAMETER': 0.0001 } cost_grid_result = processing.run('grass7:r.cost', params) if cost_grid_result and 'output' in cost_grid_result: cost_grid_raster = cost_grid_result['output'] else: feedback.reportError(f"Failed to create cost raster for Point ID: {point_id}") # Retrieving heat values point_heat_values = [ [column, feature[column]] if column in feature.fields().names() else [column, None] for column in heat_columns ] # Calculating raster based on heat values for key, value in point_heat_values: if value is None: # Skip if value is None continue a_key = key[:key.find("_")] b_key = key[key.find("_") + 1:] intvalue = int(value) try: expression = f'((A > {a_key}) * (A <= {b_key}) * {intvalue}) + ((A <= {a_key}) + (A > {b_key})) * 0' params = {'FORMULA': expression,'INPUT_A': cost_grid_raster,'BAND_A': 1,'RTYPE': 1,'OUTPUT': f"memory:recalculated_raster_{point_id}_{key}_{value}" } recalculated_result = processing.run('gdal:rastercalculator', params) recalculated_raster = recalculated_result['OUTPUT'] # SUMMING UP RASTERS ---------- if sum_raster is not None: #feedback.pushInfo(str(sum_raster)) #feedback.pushInfo(str(type(sum_raster))) #sum_raster_layer = QgsRasterLayer(sum_raster) #feedback.pushInfo(str(recalculated_raster)) #feedback.pushInfo(str(type(recalculated_raster))) #recalculated_raster_layer = QgsRasterLayer(recalculated_raster) params = {'EXPRESSION': 'A + B','LAYERS': [sum_raster, recalculated_raster],'BANDS': [1, 1],'OUTPUT': 'memory:sum_result' } feedback.pushInfo(f"Params: {params}") try: sum_result = processing.run('native:virtualrastercalc', params) sum_raster = sum_result['OUTPUT'] except Exception as e: feedback.reportError(f"Exception occurred during sum_raster calculation: {str(e)}") else: sum_raster = recalculated_raster except Exception as e: feedback.reportError(f"Exception occurred: {str(e)}") break # Exit the loop on failure return sum_raster # EXECUTING FUNCTION ---------- sum_raster = None for layer_name in plugin_updated_list: layer = results[layer_name] output_prefix = layer.name() sum_raster = process_layer(layer, output_prefix, sum_raster)
The Printout:
Processing Point ID: 3, Geometry: Point (459746.35000097844749689 5593918.35010033473372459)Creating cost grid for layer: amenity_updated, Point ID: 3, Max Reach: 400Cost raster generated: C:\Users\raven.schmidt\AppData\Local\Temp\processing_kBndzj\d012bd6872844b53b296c3601f226a26\output.ncCost raster created for Point ID: 3Heat values for point: [['0_100', 25.0], ['100_200', 10.0], ['200_300', 5.0], ['300_400', 1.0]]Processing heat value: Key: 0_100, Value: 25Recalculating raster amenity_updated 3_0_100_25.0Summing with existing sum_raster using native:virtualrastercalc<QgsRasterLayer: 'A + B' (virtualraster)><class 'qgis._core.QgsRasterLayer'>memory:recalculated_raster_3_0_100_25.0<class 'str'>Params: {'EXPRESSION': 'A + B', 'LAYERS': [<QgsRasterLayer: 'A + B' (virtualraster)>, 'memory:recalculated_raster_3_0_100_25.0'], 'BANDS': [1, 1], 'OUTPUT': 'memory:sum_result'}successfull addition
The result's properties:
All rasters have the same CRS, extent and cell size.QGIS Version is 3.34.11 LTR
Also, assuming I get this fixed, I would like to replace the gdal and grass algorithms with native:virtualrastercalc so I can do everything in memory. For those I used gdal/grass for the same reason, that native:... just didn't accept my input values.