diff --git a/qgis2fds_export_algo.py b/qgis2fds_export_algo.py index 2b97dea..eaeebcb 100644 --- a/qgis2fds_export_algo.py +++ b/qgis2fds_export_algo.py @@ -268,6 +268,21 @@ def processAlgorithm(self, parameters, context, model_feedback): extent_crs=utm_crs, ) + # Check DEM layer is local, otherwise save it + + dem_layer = DEMLayerParam.get_local( + algo=self, + parameters=parameters, + context=context, + feedback=feedback, + project=project, + extent=_transform_extent( + extent=utm_idem_extent, source_crs=utm_crs, dest_crs=dem_layer.crs() + ), # FIXME not useful here + ) + + return {} # FIXME + # Clip, reproject, and interpolate the DEM feedback.setProgressText("\nClip, reproject, and interpolate the DEM...") @@ -302,8 +317,6 @@ def processAlgorithm(self, parameters, context, model_feedback): if feedback.isCanceled(): return {} - - # Sample Z values from interpolated DEM raster layer feedback.setProgressText( @@ -617,4 +630,3 @@ def _load_fire_layer_bc( if fire_geom.contains(g): if bc != NULL: sampling_layer.changeAttributeValue(f.id(), output_bc_idx, bc) - diff --git a/qgis2fds_params.py b/qgis2fds_params.py index f1251bf..140d220 100644 --- a/qgis2fds_params.py +++ b/qgis2fds_params.py @@ -20,6 +20,9 @@ QgsProcessingParameterDefinition, QgsProcessingParameterBoolean, QgsPoint, + QgsRasterFileWriter, + QgsRasterPipe, + QgsRasterLayer, ) import os @@ -202,12 +205,6 @@ def set(cls, algo, config, project): @classmethod def get(cls, algo, parameters, context, feedback, project): value = algo.parameterAsRasterLayer(parameters, cls.label, context) - # Check local - url = value.source() - if not os.path.isfile(url): - raise QgsProcessingException( - f"DEM layer data is not saved locally, cannot proceed.\n{url}" - ) # Check valid if not value.crs().isValid(): raise QgsProcessingException( @@ -217,6 +214,69 @@ def get(cls, algo, parameters, context, feedback, project): feedback.setProgressText(f"{cls.desc}: {value}") return value + @classmethod + def get_local( + cls, + algo, + parameters, + context, + feedback, + project, + extent, # in layer crs! + relpath="./layers", + ): + layer = algo.parameterAsRasterLayer(parameters, cls.label, context) + url = layer.source() + if os.path.isfile(url): + return layer + # Make and check absolute path + project_path = project.absolutePath() + if not project_path: + raise QgsProcessingException( + "Save QGIS project to disk, cannot proceed." + ) # FIXME message + path = os.path.join(project_path, relpath) + # Create layers directory + # FIXME see https://stackoverflow.com/questions/273192/how-do-i-create-a-directory-and-any-missing-parent-directories + if not os.path.isdir(path): + feedback.setProgressText(f"Create directory {path}...") + os.makedirs(path, exist_ok=True) + if not os.path.isdir(path): + raise QgsProcessingException( + f"Error creating directory {path}, cannot proceed." + ) + # Save layer + # FIXME set style + filepath = os.path.join(path, f"{layer.name()}_saved.tif") + file_writer = QgsRasterFileWriter(filepath) + pipe = QgsRasterPipe() + provider = layer.dataProvider() + ok = pipe.set(provider.clone()) + if not ok: + raise QgsProcessingException( + f"Error saving layer data (pipe, {ok}), cannot proceed.\n{url}" + ) + feedback.setProgressText(f"pipe prepared. ok: {ok}, url: {url}, path: {path}") + nCols = round(extent.width() / layer.rasterUnitsPerPixelX()) # FIXME + nRows = round(extent.height() / layer.rasterUnitsPerPixelY()) # FIXME + # FIXME align extent with original grid + err = file_writer.writeRaster( + pipe=pipe, nCols=nCols, nRows=nRows, outputExtent=extent, crs=layer.crs() + ) + if err: + raise QgsProcessingException( + f"Error saving layer data (write, {err}), cannot proceed.\n{url}" + ) + feedback.setProgressText(f"tif saved. ok: {ok}, url: {url}, path: {filepath}") + new_layer = QgsRasterLayer(filepath, f"{layer.name()}_saved") # FIXME var name + if not new_layer.isValid(): + raise QgsProcessingException( + f"Error loading saved layer, cannot proceed.\n{url}" + ) + project.addMapLayer(new_layer) + project.writeEntry("qgis2fds", cls.label, filepath) + return new_layer + class LanduseLayerParam: label = "landuse_layer"