You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Not a bug but something to think: There's a lot of code in each map processor which could easily be in one place. One specific example is the load_rlayer_from_file and save_result_img_as_tif functions which appear identically or almost identically in MapProcessorRegression, MapProcessorSegmentation and MapProcessorSuperresolution. They would be rather easy to move, for example, to processing_utils with some changes and maybe additional parameters. I've actually refactored my fork so that MapProcessorSegmentation and MapProcessorSuperresolution use those functions from the processing_utils but later I realized that the MapProcessorRegression has yet another implementation which seems to be identical. _create_rlayers_from_images_for_base_extent is another example of such seemingly similar function appearing in multiple classes although there might be differences.
Would such a refactoring make sense as repetitive code is not a good idea in terms of bugs? Another alternative would be to move them to the super class, MapProcessor. Of course, some child classes would never use these functions, which could cause confusion.
The functions below are my implementations in the processing_utils. The differences are:
Uses QgsProcessingUtils.generateTempFilename to create temporary files. It saves to the place where QGIS processing scripts save their temporary files. In essence, it will make a uniquely named directory in which it will save the file with the same name.
Crs, geo_transform and GDAL data type are given as parameters
It is assumed that there are channels and the caller adds those to the input array before calling. It would be easily changed so that if there are no more than 1 channel, i.e. len(.img.shape) == 2, it would be single channel raster.
Uses GDAL driver.Create to directly create the dataset, instead of driver.Create and driver.CreateCopy. GeoTiff driver in GDAL supports this.
Layer name is given as a parameter for the QgsRasterLayer. There's no need to generate unique UUIDs and strip them off unless you really want to do it. The paths of the files are unique even though the filenames are not. This also saves us the hassle of joining paths. The only downside of this approach is that if you need to add these files from the directory by hand, they appear with the same name.
defsave_img_as_tif(
file_name: str,
img: np.ndarray,
crs,
geo_transform,
data_type=gdal.GDT_Float32):
""" As we cannot pass easily an numpy array to be displayed as raster layer, we create temporary geotif files, which will be loaded as layers later on. Uses QgsProcessingUtils.generateTempFilename to create a uniquely named temporary directory for saving the tempory file with the name given in `file_name`. Partially based on example from: https://gis.stackexchange.com/questions/82031/gdal-python-set-projection-of-a-raster-not-working """file_path=QgsProcessingUtils.generateTempFilename(file_name)
driver=gdal.GetDriverByName('GTiff')
n_lines=img.shape[0]
n_cols=img.shape[1]
n_chanels=img.shape[2]
grid_data=driver.Create(file_path, n_cols, n_lines, n_chanels, data_type) # , options)# loop over chanelsforiinrange(1, img.shape[2]+1):
grid_data.GetRasterBand(i).WriteArray(img[:, :, i-1])
# crs().srsid() - maybe we can use the ID directly - but how?# srs.ImportFromEPSG()srs=osr.SpatialReference()
srs.SetFromUserInput(crs.authid())
grid_data.SetProjection(srs.ExportToWkt())
grid_data.SetGeoTransform(geo_transform)
print(f'***** {file_path=}')
returnfile_pathdefload_rlayer_from_file(file_path, crs, layer_name="Temporary raster"):
""" Create raster layer from a tif file with a layer name and assign a CRS. """rlayer=QgsRasterLayer(file_path, layer_name)
ifrlayer.width() ==0:
raiseException("0 width - rlayer not loaded properly. Probably invalid file path?")
rlayer.setCrs(crs)
returnrlayer
The text was updated successfully, but these errors were encountered:
Not a bug but something to think: There's a lot of code in each map processor which could easily be in one place. One specific example is the
load_rlayer_from_file
andsave_result_img_as_tif
functions which appear identically or almost identically inMapProcessorRegression
,MapProcessorSegmentation
andMapProcessorSuperresolution
. They would be rather easy to move, for example, toprocessing_utils
with some changes and maybe additional parameters. I've actually refactored my fork so thatMapProcessorSegmentation
andMapProcessorSuperresolution
use those functions from theprocessing_utils
but later I realized that theMapProcessorRegression
has yet another implementation which seems to be identical._create_rlayers_from_images_for_base_extent
is another example of such seemingly similar function appearing in multiple classes although there might be differences.Would such a refactoring make sense as repetitive code is not a good idea in terms of bugs? Another alternative would be to move them to the super class, MapProcessor. Of course, some child classes would never use these functions, which could cause confusion.
The functions below are my implementations in the
processing_utils
. The differences are:QgsProcessingUtils.generateTempFilename
to create temporary files. It saves to the place where QGIS processing scripts save their temporary files. In essence, it will make a uniquely named directory in which it will save the file with the same name.driver.Create
to directly create the dataset, instead ofdriver.Create
anddriver.CreateCopy
. GeoTiff driver in GDAL supports this.The text was updated successfully, but these errors were encountered: