The data I have are ESRI Floating Point Data (so they are a raster type). The path I provided is a fake path, so that I don't show my real system paths.
I know that my code works with vector data, as I wrote this script, just for other data-types (.shp, .gpkg). Therefore, I assume, that the algorithm doesn't work with the flt-type.
... and indeed it doesn't. For reprojecting raster data, there is the algorithm warp
.
So what I did yesterday was to use batch processing for applying the warp-function to the flt-data. The decision to not adapt the python script to warp the data but to use the batch-processing-functionality was just that it was a good opportunity to try it out (never worked with batches before).
I have a couple of .flt-files and I would like to reproject them to another CRS. In QGIS desktop, you can load the .flt-files by just dragging and dropping the file.
However, when I try to load the files in PyQGIS it says:
Could not load source layer for INPUT: path/to/3257559305385.flt not found
My code is just a function which uses the processing module. Is it somehow possible to load .flt-data in PyQGIS?
def reprojectFLTfiles(inputfolderpath, outputfolderpath, crs):
for fltfile_name in os.listdir(inputfolderpath):
if '.flt' in fltfile_name:
if 'xml' not in fltfile_name:
print(fltfile_name)
INPUT = inputfolderpath + '/' + fltfile_name
OUTPUT = outputfolderpath + '/' + fltfile_name
print(INPUT)
print(OUTPUT)
processing.run("qgis:reprojectlayer",
{'INPUT':INPUT,
'TARGET_CRS':crs,
'OUTPUT':OUTPUT
}
)
1 Answer 1
I would agree with @BenW's comment, that your binary floating-point files can not be found under this path inputfolderpath + '/' + fltfile_name
. However, I could also say, that your input does not match any of the INPUT
accepted data types. See, that "Reproject layer" geoalgorithm reprojects a vector layer in a different CRS. See the GDAL Vector drivers for more details.
⚠️ For raster data types, use the "Warp (reproject)", see the GDAL Raster drivers for more details.
Your binary floating-point file with a .flt extension should come with an ASCII header file that has a .hdr extension, see EHdr -- ESRI .hdr Labelled. You only specify the .flt file; however, there needs to be an existing .hdr file in the same directory with the same file name.
There are several suggestions to your code:
check firstly alg input and output by means of the
processing.algorithmHelp("qgis:reprojectlayer")
INPUT: Input layer Parameter type: QgsProcessingParameterFeatureSource Accepted data types: - str: layer ID - str: layer name - str: layer source - QgsProcessingFeatureSourceDefinition - QgsProperty - QgsVectorLayer OUTPUT: Reprojected Parameter type: QgsProcessingParameterFeatureSink Accepted data types: - str: destination vector file, e.g. 'd:/test.shp' - str: 'memory:' to store result in temporary memory layer - str: using vector provider ID prefix and destination URI, e.g. 'postgres:...' to store result in PostGIS table - QgsProcessingOutputLayerDefinition - QgsProperty
apply the
isfile()
function from theos.path
library to check if a file existsif isfile(INPUT): ...
Or, as was mentioned by @BenW, apply the
exists()
function. This functionisdir()
can also be handy for dirs.better to work with a normalized path, can be achieved with the
normpath()
functionfor fltfile_name in listdir(normpath(inputfolderpath)):
two
if
-statements can be combined into oneif '.flt' in fltfile_name and not ('xml' in fltfile_name): ...
make use of the
join()
function to get a proper file pathINPUT = join(inputfolderpath, fltfile_name)
use the Python Try Except blocks to handle errors and exceptions e.g.
QgsProcessingException
.try: params = { 'INPUT': INPUT, 'TARGET_CRS': crs, 'OUTPUT': OUTPUT } processing.run("qgis:reprojectlayer", params) return True except QgsProcessingException: return False
The QGIS processing algorithm also has a
checkParameterValues()
-method:Checks the supplied parameter values to verify that they satisfy the requirements of this algorithm in the supplied context.
The message parameter will be filled with explanatory text if validation fails. Overridden implementations should also check this base class implementation.
it is not clear yet in which form you provide the
crs
value, but there is a classQgsCoordinateReferenceSystem()
, that facilitates creation and work with CRScrs = QgsCoordinateReferenceSystem.fromEpsgId(4326)
imports can be useful to make your code reusable in the future in standalone applications
# imports import processing from qgis.core import QgsCoordinateReferenceSystem from os import listdir from os.path import isfile, join, normpath
add some
reprojectFLTfiles
descriptions, see the PEP 20 – The Zen of Python for more inspirationdef reprojectFLTfiles(inputfolderpath: str, outputfolderpath: str, crs: int) -> bool: """ Reprojects a FTL file using a certain CRS Parameters: ========== :param inputfolderpath: :param outputfolderpath: :param crs: Returns: ========== :return: """
So, in the end, it may look like this:
# imports
import processing
from qgis.core import QgsCoordinateReferenceSystem
from os import listdir
from os.path import isfile, join, normpath
def reprojectFLTfiles(inputfolderpath: str, outputfolderpath: str, epsg_code: int) -> bool:
"""
Reprojects FTL file to a certain CRS
Parameters:
==========
:param inputfolderpath:
:param outputfolderpath:
:param crs:
Returns:
==========
:return:
"""
crs = QgsCoordinateReferenceSystem.fromEpsgId(epsg_code)
for fltfile_name in listdir(inputfolderpath):
if '.gpkg' in fltfile_name and not ('xml' in fltfile_name):
INPUT = join(inputfolderpath, fltfile_name)
if isfile(INPUT):
OUTPUT = join(outputfolderpath, fltfile_name)
try:
params = {
'INPUT': INPUT,
'TARGET_CRS': crs,
'OUTPUT': OUTPUT
}
processing.run("qgis:reprojectlayer", params)
return True
except QgsProcessingException as e:
print(f'Could not reproject this {INPUT} file. Ended with the following error:')
print(e)
return False
reprojectFLTfiles('D:/qgis_test/', 'D:/qgis_test/temp/', 4326)
With the code above, I could reproject my GeoPackage from EPSG:32637
into EPSG:4326
.
References:
-
Thank you so much for the effort! Very helpful, however, I didn't specify the flt-data: it are floating-point-data from ESRI. I updated the question accordingly!i.i.k.– i.i.k.2024年02月20日 08:22:26 +00:00Commented Feb 20, 2024 at 8:22
Explore related questions
See similar questions with these tags.
inputfolderpath
look like? Does the print statement print the the correctINPUT
path string? Can you verify it withos.path.exists()
? As a better practice, I would encourage you to useos.path.join()
instead of the string arithmetic.