I need the exact source path of layer files as shown by QGIS Layer Properties Information Window:
I know how to retrieve the layer source URI (and using the data provider gives the same result):
layer = qgis.utils.iface.activeLayer()
uri = layer.source()
# uri = layer.dataProvider().dataSourceUri()
Now retrieving the exact layer source path from the URI is not a trivial thing, as it contains information depending on the data provider type.
layer.providerType() == 'delimitedtext' can look something like that:
"file:///home/ubuntu/QGIS/Ciutat%20pr%C3%B2xima%201.0/EDUCACI%C3%93/opendatabcn_llista-equipaments_educacio-csv.csv?encoding=UTF-16&type=csv&maxFields=10000&detectTypes=yes&xField=geo_epgs_25831_x&yField=geo_epgs_25831_y&crs=EPSG:25831&spatialIndex=no&subsetIndex=no&watchFile=no&subset=%20%22secondary_filters_name%22%20%3D%20'Universitat'%20or%20%22secondary_filters_name%22%20%3D%20'Educaci%C3%B3%20secund%C3%A0ria'%20or%20%22secondary_filters_name%22%20%3D%20'Educaci%C3%B3%20prim%C3%A0ria'%20or%20%20%22secondary_filters_name%22%20%3D%20%20%20'Ensenyament%20infantil%20(3-6%20anys)'%20%20%20or%20%20%22secondary_filters_name%22%20%3D%20%20'Ensenyament%20infantil%20(0-3%20anys)'%20or%20%22secondary_filters_name%22%20%3D%20%20%20'Escoles%20Bressol%20municipals'%20"
layer.providerType() == 'ogr' could look like that:
'/vsizip//home/ubuntu/QGIS/Ciutat pròxima 1.0/DEMOGRAFIA/BCN_UNITATS_ADM.zip/0301100100_UNITATS_ADM_POLIGONS.json|layername=0301100100_UNITATS_ADM_POLIGONS|geometrytype=Polygon|subset="CONJ_DESCR"=\'Districtes\''
So it's actually possible to get the layer source path as shown in QGIS, but is there a easy way to do that?
PS: I know this question in a quite similar way has been asked before, but always in a different context or with ambiguous descriptions, like this one (which asked 2 questions at the same time) and this one (which asks about running it as a daemon).
1 Answer 1
There is a method called decodeURI
which can be used to break down the data source URI into the core path and all other components.
The documentation states that this function may not be supported by all provider types, but for delimited text layers and ogr it definitely works as shown below:
>>> layer = iface.activeLayer()
>>> uri_components = QgsProviderRegistry.instance().decodeUri(layer.dataProvider().name(), layer.publicSource());
>>> layer.source()
'file:///D:/Downloads/agency.txt?type=csv&maxFields=10000&detectTypes=yes&geomType=none&subsetIndex=no&watchFile=no'
>>> uri_components['path']
'D:/Downloads/agency.txt'
source
exists. But you can check provider type and split the given path by specific character like?
,|
to get the source file path.os.path.split(uri)
oros.path.basepath(uri)
) you still don't have a valid path as shown by the 2 examples above. For sure it's possible to removefile://
and/vsizip/
, but I need a more secure way of doing that, is has to work for all possible provider types.